    {-# LANGUAGE CPP                 #-}
    {-# LANGUAGE DataKinds           #-}
    {-# LANGUAGE KindSignatures      #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Data.Aeson.Extra.SymTag
    -- Copyright   :  (C) 2015-2018 Oleg Grenrus
    -- License     :  BSD3
    -- Maintainer  :  Oleg Grenrus <oleg.grenrus@iki.fi>
    --
    module Data.Aeson.Extra.SymTag (
        SymTag(..),
        ) where

    import Prelude ()
    import Prelude.Compat

    import Control.DeepSeq  (NFData (..))
    import Data.Aeson
    import Data.Aeson.Types hiding ((.:?))
    import Data.Proxy       (Proxy (..))
    import GHC.TypeLits     (KnownSymbol, Symbol, symbolVal)

    import qualified Data.Text as T

    -- | Singleton string encoded and decoded as ifself.
    --
    -- > λ> encode (SymTag :: SymTag "foobar")
    -- > "\"foobar\""
    --
    -- > decode "\"foobar\"" :: Maybe (SymTag "foobar")
    -- > Just SymTag
    --
    -- > decode "\"foobar\"" :: Maybe (SymTag "barfoo")
    -- > Nothing
    --
    -- /Available with: base >=4.7/
    data SymTag (s :: Symbol) = SymTag
      deriving (SymTag s -> SymTag s -> Bool
    (SymTag s -> SymTag s -> Bool)
    -> (SymTag s -> SymTag s -> Bool) -> Eq (SymTag s)
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    $c== :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    == :: SymTag s -> SymTag s -> Bool
    $c/= :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    /= :: SymTag s -> SymTag s -> Bool
    Eq, Eq (SymTag s)
    Eq (SymTag s)
    -> (SymTag s -> SymTag s -> Ordering)
    -> (SymTag s -> SymTag s -> Bool)
    -> (SymTag s -> SymTag s -> Bool)
    -> (SymTag s -> SymTag s -> Bool)
    -> (SymTag s -> SymTag s -> Bool)
    -> (SymTag s -> SymTag s -> SymTag s)
    -> (SymTag s -> SymTag s -> SymTag s)
    -> Ord (SymTag s)
    SymTag s -> SymTag s -> Bool
    SymTag s -> SymTag s -> Ordering
    SymTag s -> SymTag s -> SymTag s
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    forall (s :: Symbol). Eq (SymTag s)
    forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    forall (s :: Symbol). SymTag s -> SymTag s -> Ordering
    forall (s :: Symbol). SymTag s -> SymTag s -> SymTag s
    $ccompare :: forall (s :: Symbol). SymTag s -> SymTag s -> Ordering
    compare :: SymTag s -> SymTag s -> Ordering
    $c< :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    < :: SymTag s -> SymTag s -> Bool
    $c<= :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    <= :: SymTag s -> SymTag s -> Bool
    $c> :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    > :: SymTag s -> SymTag s -> Bool
    $c>= :: forall (s :: Symbol). SymTag s -> SymTag s -> Bool
    >= :: SymTag s -> SymTag s -> Bool
    $cmax :: forall (s :: Symbol). SymTag s -> SymTag s -> SymTag s
    max :: SymTag s -> SymTag s -> SymTag s
    $cmin :: forall (s :: Symbol). SymTag s -> SymTag s -> SymTag s
    min :: SymTag s -> SymTag s -> SymTag s
    Ord, Int -> SymTag s -> ShowS
    [SymTag s] -> ShowS
    SymTag s -> String
    (Int -> SymTag s -> ShowS)
    -> (SymTag s -> String) -> ([SymTag s] -> ShowS) -> Show (SymTag s)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (s :: Symbol). Int -> SymTag s -> ShowS
    forall (s :: Symbol). [SymTag s] -> ShowS
    forall (s :: Symbol). SymTag s -> String
    $cshowsPrec :: forall (s :: Symbol). Int -> SymTag s -> ShowS
    showsPrec :: Int -> SymTag s -> ShowS
    $cshow :: forall (s :: Symbol). SymTag s -> String
    show :: SymTag s -> String
    $cshowList :: forall (s :: Symbol). [SymTag s] -> ShowS
    showList :: [SymTag s] -> ShowS
    Show, ReadPrec [SymTag s]
    ReadPrec (SymTag s)
    Int -> ReadS (SymTag s)
    ReadS [SymTag s]
    (Int -> ReadS (SymTag s))
    -> ReadS [SymTag s]
    -> ReadPrec (SymTag s)
    -> ReadPrec [SymTag s]
    -> Read (SymTag s)
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    forall (s :: Symbol). ReadPrec [SymTag s]
    forall (s :: Symbol). ReadPrec (SymTag s)
    forall (s :: Symbol). Int -> ReadS (SymTag s)
    forall (s :: Symbol). ReadS [SymTag s]
    $creadsPrec :: forall (s :: Symbol). Int -> ReadS (SymTag s)
    readsPrec :: Int -> ReadS (SymTag s)
    $creadList :: forall (s :: Symbol). ReadS [SymTag s]
    readList :: ReadS [SymTag s]
    $creadPrec :: forall (s :: Symbol). ReadPrec (SymTag s)
    readPrec :: ReadPrec (SymTag s)
    $creadListPrec :: forall (s :: Symbol). ReadPrec [SymTag s]
    readListPrec :: ReadPrec [SymTag s]
    Read, Int -> SymTag s
    SymTag s -> Int
    SymTag s -> [SymTag s]
    SymTag s -> SymTag s
    SymTag s -> SymTag s -> [SymTag s]
    SymTag s -> SymTag s -> SymTag s -> [SymTag s]
    (SymTag s -> SymTag s)
    -> (SymTag s -> SymTag s)
    -> (Int -> SymTag s)
    -> (SymTag s -> Int)
    -> (SymTag s -> [SymTag s])
    -> (SymTag s -> SymTag s -> [SymTag s])
    -> (SymTag s -> SymTag s -> [SymTag s])
    -> (SymTag s -> SymTag s -> SymTag s -> [SymTag s])
    -> Enum (SymTag s)
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    forall (s :: Symbol). Int -> SymTag s
    forall (s :: Symbol). SymTag s -> Int
    forall (s :: Symbol). SymTag s -> [SymTag s]
    forall (s :: Symbol). SymTag s -> SymTag s
    forall (s :: Symbol). SymTag s -> SymTag s -> [SymTag s]
    forall (s :: Symbol).
    SymTag s -> SymTag s -> SymTag s -> [SymTag s]
    $csucc :: forall (s :: Symbol). SymTag s -> SymTag s
    succ :: SymTag s -> SymTag s
    $cpred :: forall (s :: Symbol). SymTag s -> SymTag s
    pred :: SymTag s -> SymTag s
    $ctoEnum :: forall (s :: Symbol). Int -> SymTag s
    toEnum :: Int -> SymTag s
    $cfromEnum :: forall (s :: Symbol). SymTag s -> Int
    fromEnum :: SymTag s -> Int
    $cenumFrom :: forall (s :: Symbol). SymTag s -> [SymTag s]
    enumFrom :: SymTag s -> [SymTag s]
    $cenumFromThen :: forall (s :: Symbol). SymTag s -> SymTag s -> [SymTag s]
    enumFromThen :: SymTag s -> SymTag s -> [SymTag s]
    $cenumFromTo :: forall (s :: Symbol). SymTag s -> SymTag s -> [SymTag s]
    enumFromTo :: SymTag s -> SymTag s -> [SymTag s]
    $cenumFromThenTo :: forall (s :: Symbol).
    SymTag s -> SymTag s -> SymTag s -> [SymTag s]
    enumFromThenTo :: SymTag s -> SymTag s -> SymTag s -> [SymTag s]
    Enum, SymTag s
    SymTag s -> SymTag s -> Bounded (SymTag s)
    forall a. a -> a -> Bounded a
    forall (s :: Symbol). SymTag s
    $cminBound :: forall (s :: Symbol). SymTag s
    minBound :: SymTag s
    $cmaxBound :: forall (s :: Symbol). SymTag s
    maxBound :: SymTag s
    Bounded)

    instance KnownSymbol s => FromJSON (SymTag s) where
      parseJSON :: Value -> Parser (SymTag s)
    parseJSON (String Text
    t)
        | Text -> String
    T.unpack Text
    t String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == Proxy s -> String
    forall (n :: Symbol) (proxy :: Symbol -> *).
    KnownSymbol n =>
    proxy n -> String
    symbolVal (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s) = SymTag s -> Parser (SymTag s)
    forall a. a -> Parser a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure SymTag s
    forall (s :: Symbol). SymTag s
    SymTag
      parseJSON Value
    v = String -> Value -> Parser (SymTag s)
    forall a. String -> Value -> Parser a
    typeMismatch (String
    "SymTag " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ ShowS
    forall a. Show a => a -> String
    show (Proxy s -> String
    forall (n :: Symbol) (proxy :: Symbol -> *).
    KnownSymbol n =>
    proxy n -> String
    symbolVal (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s))) Value
    v

    instance KnownSymbol s => ToJSON (SymTag s) where
    #if MIN_VERSION_aeson (0,10,0)
      toEncoding :: SymTag s -> Encoding
    toEncoding SymTag s
    _ = String -> Encoding
    forall a. ToJSON a => a -> Encoding
    toEncoding (Proxy s -> String
    forall (n :: Symbol) (proxy :: Symbol -> *).
    KnownSymbol n =>
    proxy n -> String
    symbolVal (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s))
    #endif
      toJSON :: SymTag s -> Value
    toJSON SymTag s
    _ = String -> Value
    forall a. ToJSON a => a -> Value
    toJSON (Proxy s -> String
    forall (n :: Symbol) (proxy :: Symbol -> *).
    KnownSymbol n =>
    proxy n -> String
    symbolVal (Proxy s
    forall {k} (t :: k). Proxy t
    Proxy :: Proxy s))

    -- | @since 0.4.1.0
    instance NFData (SymTag s) where
        rnf :: SymTag s -> ()
    rnf SymTag s
    SymTag = ()