{-# 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 = Set a
forall a. Set a
Set.empty
toEnumBaseType :: a -> EnumBaseType a
:: EnumBaseType a -> Maybe a
default :: (LspOpenEnum a) => EnumBaseType a -> Maybe a
fromEnumBaseType = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a)
-> (EnumBaseType a -> a) -> EnumBaseType a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EnumBaseType a -> a
forall a. LspOpenEnum a => EnumBaseType a -> a
fromOpenEnumBaseType
class LspEnum a => LspOpenEnum a where
fromOpenEnumBaseType :: EnumBaseType a -> a
newtype AsLspEnum a = AsLspEnum a
instance (LspEnum a, EnumBaseType a ~ b, Aeson.ToJSON b) => Aeson.ToJSON (AsLspEnum a) where
toJSON :: AsLspEnum a -> Value
toJSON (AsLspEnum a
e) = b -> Value
forall a. ToJSON a => a -> Value
Aeson.toJSON (a -> EnumBaseType a
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) where
parseJSON :: Value -> Parser (AsLspEnum a)
parseJSON Value
val = do
b
v <- Value -> Parser b
forall a. FromJSON a => Value -> Parser a
Aeson.parseJSON Value
val
case EnumBaseType a -> Maybe a
forall a. LspEnum a => EnumBaseType a -> Maybe a
fromEnumBaseType b
EnumBaseType a
v of
Just a
x -> AsLspEnum a -> Parser (AsLspEnum a)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (AsLspEnum a -> Parser (AsLspEnum a))
-> AsLspEnum a -> Parser (AsLspEnum a)
forall a b. (a -> b) -> a -> b
$ a -> AsLspEnum a
forall a. a -> AsLspEnum a
AsLspEnum a
x
Maybe a
Nothing -> [Char] -> Parser (AsLspEnum a)
forall a. [Char] -> Parser a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> Parser (AsLspEnum a)) -> [Char] -> Parser (AsLspEnum a)
forall a b. (a -> b) -> a -> b
$ [Char]
"unrecognized enum value " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ b -> [Char]
forall a. Show a => a -> [Char]
show b
v
instance (LspOpenEnum a, EnumBaseType a ~ b, b ~ Text.Text) => IsString (AsLspEnum a) where
fromString :: [Char] -> AsLspEnum a
fromString [Char]
s = a -> AsLspEnum a
forall a. a -> AsLspEnum a
AsLspEnum (a -> AsLspEnum a) -> a -> AsLspEnum a
forall a b. (a -> b) -> a -> b
$ EnumBaseType a -> a
forall a. LspOpenEnum a => EnumBaseType a -> a
fromOpenEnumBaseType ([Char] -> Text
Text.pack [Char]
s)