{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE TypeFamilies #-}
module Language.LSP.Protocol.Types.LspEnum where
import Data.Aeson qualified as Aeson
import Data.Kind
import Data.Set qualified as Set
import Data.String (IsString (..))
import Data.Text qualified as Text
class LspEnum a where
type EnumBaseType a :: Type
knownValues :: Set.Set a
knownValues = forall a. Set a
Set.empty
toEnumBaseType :: a -> EnumBaseType a
:: EnumBaseType a -> Maybe a
default :: (LspOpenEnum a) => EnumBaseType a -> Maybe a
fromEnumBaseType = forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. LspOpenEnum a => EnumBaseType a -> a
fromOpenEnumBaseType
class LspEnum a => LspOpenEnum a where
fromOpenEnumBaseType :: EnumBaseType a -> a
newtype AsLspEnum a b = AsLspEnum a
instance (LspEnum a, EnumBaseType a ~ b, Aeson.ToJSON b) => Aeson.ToJSON (AsLspEnum a b) where
toJSON :: AsLspEnum a b -> Value
toJSON (AsLspEnum a
e) = forall a. ToJSON a => a -> Value
Aeson.toJSON (forall a. LspEnum a => a -> EnumBaseType a
toEnumBaseType a
e)
instance (LspEnum a, EnumBaseType a ~ b, Aeson.FromJSON b, Show b) => Aeson.FromJSON (AsLspEnum a b) where
parseJSON :: Value -> Parser (AsLspEnum a b)
parseJSON Value
val = do
b
v <- forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON Value
val
case forall a. LspEnum a => EnumBaseType a -> Maybe a
fromEnumBaseType b
v of
Just a
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} a (b :: k). a -> AsLspEnum a b
AsLspEnum a
x
Maybe a
Nothing -> forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail forall a b. (a -> b) -> a -> b
$ [Char]
"unrecognized enum value " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show b
v
instance (LspOpenEnum a, EnumBaseType a ~ b, b ~ Text.Text) => IsString (AsLspEnum a b) where
fromString :: [Char] -> AsLspEnum a b
fromString [Char]
s = forall {k} a (b :: k). a -> AsLspEnum a b
AsLspEnum forall a b. (a -> b) -> a -> b
$ forall a. LspOpenEnum a => EnumBaseType a -> a
fromOpenEnumBaseType ([Char] -> Text
Text.pack [Char]
s)