{-# Language DataKinds, InstanceSigs, ScopedTypeVariables, TypeOperators #-}
module Toml.Schema.Generic.FromValue (
    
    GParseTable(..),
    genericParseTable,
    genericFromTable,
    
    GFromArray(..),
    genericFromArray,
    ) where
import Control.Monad.Trans.State (StateT(..))
import Data.Coerce (coerce)
import Data.Text qualified as Text
import GHC.Generics
import Toml.Schema.FromValue (FromValue, fromValue, optKey, reqKey, parseTableFromValue, typeError)
import Toml.Schema.Matcher (Matcher, failAt)
import Toml.Schema.ParseTable (ParseTable)
import Toml.Semantics (Value'(List'))
genericParseTable :: (Generic a, GParseTable (Rep a)) => ParseTable l a
genericParseTable :: forall a l. (Generic a, GParseTable (Rep a)) => ParseTable l a
genericParseTable = Rep a Any -> a
forall a x. Generic a => Rep a x -> a
forall x. Rep a x -> a
to (Rep a Any -> a) -> ParseTable l (Rep a Any) -> ParseTable l a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseTable l (Rep a Any)
forall l a. ParseTable l (Rep a a)
forall (f :: * -> *) l a. GParseTable f => ParseTable l (f a)
gParseTable
{-# INLINE genericParseTable #-}
genericFromTable :: (Generic a, GParseTable (Rep a)) => Value' l -> Matcher l a
genericFromTable :: forall a l.
(Generic a, GParseTable (Rep a)) =>
Value' l -> Matcher l a
genericFromTable = ParseTable l a -> Value' l -> Matcher l a
forall l a. ParseTable l a -> Value' l -> Matcher l a
parseTableFromValue ParseTable l a
forall a l. (Generic a, GParseTable (Rep a)) => ParseTable l a
genericParseTable
{-# INLINE genericFromTable #-}
genericFromArray :: (Generic a, GFromArray (Rep a)) => Value' l -> Matcher l a
genericFromArray :: forall a l.
(Generic a, GFromArray (Rep a)) =>
Value' l -> Matcher l a
genericFromArray (List' l
a [Value' l]
xs) =
 do (Rep a Any
gen, [Value' l]
xs') <- StateT [Value' l] (Matcher l) (Rep a Any)
-> [Value' l] -> Matcher l (Rep a Any, [Value' l])
forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
runStateT StateT [Value' l] (Matcher l) (Rep a Any)
forall l a. StateT [Value' l] (Matcher l) (Rep a a)
forall (f :: * -> *) l a.
GFromArray f =>
StateT [Value' l] (Matcher l) (f a)
gFromArray [Value' l]
xs
    if [Value' l] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Value' l]
xs' then
        a -> Matcher l a
forall a. a -> Matcher l a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Rep a Any -> a
forall a x. Generic a => Rep a x -> a
forall x. Rep a x -> a
to Rep a Any
gen)
    else
        l -> String -> Matcher l a
forall l a. l -> String -> Matcher l a
failAt l
a (String
"array " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([Value' l] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Value' l]
xs') String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" elements too long")
genericFromArray Value' l
v = String -> Value' l -> Matcher l a
forall l a. String -> Value' l -> Matcher l a
typeError String
"array" Value' l
v
{-# INLINE genericFromArray #-}
class GParseTable f where
    
    gParseTable :: ParseTable l (f a)
instance GParseTable f => GParseTable (D1 c f) where
    gParseTable :: forall l a. ParseTable l (D1 c f a)
gParseTable = f a -> M1 D c f a
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f a -> M1 D c f a)
-> ParseTable l (f a) -> ParseTable l (M1 D c f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>  ParseTable l (f a)
forall l a. ParseTable l (f a)
forall (f :: * -> *) l a. GParseTable f => ParseTable l (f a)
gParseTable
    {-# INLINE gParseTable #-}
instance GParseTable f => GParseTable (C1 ('MetaCons sym fix 'True) f) where
    gParseTable :: forall l a. ParseTable l (C1 ('MetaCons sym fix 'True) f a)
gParseTable = f a -> M1 C ('MetaCons sym fix 'True) f a
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (f a -> M1 C ('MetaCons sym fix 'True) f a)
-> ParseTable l (f a)
-> ParseTable l (M1 C ('MetaCons sym fix 'True) f a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParseTable l (f a)
forall l a. ParseTable l (f a)
forall (f :: * -> *) l a. GParseTable f => ParseTable l (f a)
gParseTable
    {-# INLINE gParseTable #-}
instance (GParseTable f, GParseTable g) => GParseTable (f :*: g) where
    gParseTable :: forall l a. ParseTable l ((:*:) f g a)
gParseTable =
     do f a
x <- ParseTable l (f a)
forall l a. ParseTable l (f a)
forall (f :: * -> *) l a. GParseTable f => ParseTable l (f a)
gParseTable
        g a
y <- ParseTable l (g a)
forall l a. ParseTable l (g a)
forall (f :: * -> *) l a. GParseTable f => ParseTable l (f a)
gParseTable
        (:*:) f g a -> ParseTable l ((:*:) f g a)
forall a. a -> ParseTable l a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (f a
x f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a
y)
    {-# INLINE gParseTable #-}
instance {-# OVERLAPS #-} (Selector s, FromValue a) => GParseTable (S1 s (K1 i (Maybe a))) where
    gParseTable :: forall l a. ParseTable l (S1 s (K1 i (Maybe a)) a)
gParseTable =
     do Maybe a
x <- Text -> ParseTable l (Maybe a)
forall a l. FromValue a => Text -> ParseTable l (Maybe a)
optKey (String -> Text
Text.pack (M1 S s [] () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName ([()] -> M1 S s [] ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 [] :: S1 s [] ())))
        S1 s (K1 i (Maybe a)) a -> ParseTable l (S1 s (K1 i (Maybe a)) a)
forall a. a -> ParseTable l a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (K1 i (Maybe a) a -> S1 s (K1 i (Maybe a)) a
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (Maybe a -> K1 i (Maybe a) a
forall k i c (p :: k). c -> K1 i c p
K1 Maybe a
x))
    {-# INLINE gParseTable #-}
instance (Selector s, FromValue a) => GParseTable (S1 s (K1 i a)) where
    gParseTable :: forall l a. ParseTable l (S1 s (K1 i a) a)
gParseTable =
     do a
x <- Text -> ParseTable l a
forall a l. FromValue a => Text -> ParseTable l a
reqKey (String -> Text
Text.pack (M1 S s [] () -> String
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
       (f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> String
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
       (a :: k1).
t s f a -> String
selName ([()] -> M1 S s [] ()
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 [] :: S1 s [] ())))
        S1 s (K1 i a) a -> ParseTable l (S1 s (K1 i a) a)
forall a. a -> ParseTable l a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (K1 i a a -> S1 s (K1 i a) a
forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
M1 (a -> K1 i a a
forall k i c (p :: k). c -> K1 i c p
K1 a
x))
    {-# INLINE gParseTable #-}
instance GParseTable U1 where
    gParseTable :: forall l a. ParseTable l (U1 a)
gParseTable = U1 a -> ParseTable l (U1 a)
forall a. a -> ParseTable l a
forall (f :: * -> *) a. Applicative f => a -> f a
pure U1 a
forall k (p :: k). U1 p
U1
    {-# INLINE gParseTable #-}
class GFromArray f where
    gFromArray :: StateT [Value' l] (Matcher l) (f a)
instance GFromArray f => GFromArray (M1 i c f) where
    gFromArray :: forall a l. StateT [Value' l] (Matcher l) (M1 i c f a)
    gFromArray :: forall a l. StateT [Value' l] (Matcher l) (M1 i c f a)
gFromArray = StateT [Value' l] (Matcher l) (f a)
-> StateT [Value' l] (Matcher l) (M1 i c f a)
forall a b. Coercible a b => a -> b
coerce (StateT [Value' l] (Matcher l) (f a)
forall l a. StateT [Value' l] (Matcher l) (f a)
forall (f :: * -> *) l a.
GFromArray f =>
StateT [Value' l] (Matcher l) (f a)
gFromArray :: StateT [Value' l] (Matcher l) (f a))
    {-# INLINE gFromArray #-}
instance (GFromArray f, GFromArray g) => GFromArray (f :*: g) where
    gFromArray :: forall l a. StateT [Value' l] (Matcher l) ((:*:) f g a)
gFromArray =
     do f a
x <- StateT [Value' l] (Matcher l) (f a)
forall l a. StateT [Value' l] (Matcher l) (f a)
forall (f :: * -> *) l a.
GFromArray f =>
StateT [Value' l] (Matcher l) (f a)
gFromArray
        g a
y <- StateT [Value' l] (Matcher l) (g a)
forall l a. StateT [Value' l] (Matcher l) (g a)
forall (f :: * -> *) l a.
GFromArray f =>
StateT [Value' l] (Matcher l) (f a)
gFromArray
        (:*:) f g a -> StateT [Value' l] (Matcher l) ((:*:) f g a)
forall a. a -> StateT [Value' l] (Matcher l) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (f a
x f a -> g a -> (:*:) f g a
forall k (f :: k -> *) (g :: k -> *) (p :: k).
f p -> g p -> (:*:) f g p
:*: g a
y)
    {-# INLINE gFromArray #-}
instance FromValue a => GFromArray (K1 i a) where
    gFromArray :: forall l a. StateT [Value' l] (Matcher l) (K1 i a a)
gFromArray = ([Value' l] -> Matcher l (K1 i a a, [Value' l]))
-> StateT [Value' l] (Matcher l) (K1 i a a)
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT \case
        [] -> String -> Matcher l (K1 i a a, [Value' l])
forall a. String -> Matcher l a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"array too short"
        Value' l
x:[Value' l]
xs -> (\a
v -> (a -> K1 i a a
forall k i c (p :: k). c -> K1 i c p
K1 a
v, [Value' l]
xs)) (a -> (K1 i a a, [Value' l]))
-> Matcher l a -> Matcher l (K1 i a a, [Value' l])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value' l -> Matcher l a
forall l. Value' l -> Matcher l a
forall a l. FromValue a => Value' l -> Matcher l a
fromValue Value' l
x
    {-# INLINE gFromArray #-}
instance GFromArray U1 where
    gFromArray :: forall l a. StateT [Value' l] (Matcher l) (U1 a)
gFromArray = U1 a -> StateT [Value' l] (Matcher l) (U1 a)
forall a. a -> StateT [Value' l] (Matcher l) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure U1 a
forall k (p :: k). U1 p
U1
    {-# INLINE gFromArray #-}