{-# LANGUAGE FlexibleInstances, UndecidableInstances, ScopedTypeVariables, InstanceSigs #-} {-| Module : Toml.Schema.Generic Description : Integration with DerivingVia extension Copyright : (c) Eric Mertens, 2024 License : ISC Maintainer : emertens@gmail.com This module makes it possible to easily derive the TOML classes using the @DerivingVia@ extension. For example: @ data Physical = Physical { color :: String, shape :: String } deriving (Eq, Show, Generic) deriving (ToTable, ToValue, FromValue) via GenericTomlTable Physical @ These derived instances would allow you to match TOML @{color="red", shape="round"}@ to value @Physical "red" "round"@. @ data Coord = Coord Int Int deriving (Eq, Show, Generic) deriving (ToValue, FromValue) via GenericTomlArray Physical @ These derived instances would allow you to match TOML @[1,2]@ to value @Coord 1 2@. -} module Toml.Schema.Generic ( -- * DerivingVia GenericTomlTable(GenericTomlTable), GenericTomlArray(GenericTomlArray), -- * FromValue genericFromArray, genericFromTable, GFromArray, GParseTable, -- * ToValue genericToArray, genericToTable, GToArray, GToTable, ) where import Data.Coerce (coerce) import GHC.Generics (Generic(Rep)) import Toml.Schema.FromValue import Toml.Schema.Matcher import Toml.Schema.Generic.FromValue import Toml.Schema.Generic.ToValue (GToTable, GToArray, genericToTable, genericToArray) import Toml.Schema.ToValue (ToTable(toTable), ToValue(toValue), defaultTableToValue) import Toml.Semantics (Value, Value', Table) -- | Helper type to use GHC's DerivingVia extension to derive -- 'ToValue', 'ToTable', 'FromValue' for records. newtype GenericTomlTable a = GenericTomlTable a -- | Instance derived from 'ToTable' instance using 'defaultTableToValue' instance (Generic a, GToTable (Rep a)) => ToValue (GenericTomlTable a) where toValue = defaultTableToValue {-# INLINE toValue #-} -- | Instance derived using 'genericToTable' instance (Generic a, GToTable (Rep a)) => ToTable (GenericTomlTable a) where toTable = coerce (genericToTable :: a -> Table) {-# INLINE toTable #-} -- | Instance derived using 'genericParseTable' instance (Generic a, GParseTable (Rep a)) => FromValue (GenericTomlTable a) where fromValue :: forall l. Value' l -> Matcher l (GenericTomlTable a) fromValue = coerce (parseTableFromValue genericParseTable :: Value' l -> Matcher l a) {-# INLINE fromValue #-} -- | Helper type to use GHC's DerivingVia extension to derive -- 'ToValue', 'ToTable', 'FromValue' for any product type. newtype GenericTomlArray a = GenericTomlArray a -- | Instance derived using 'genericToArray' instance (Generic a, GToArray (Rep a)) => ToValue (GenericTomlArray a) where toValue = coerce (genericToArray :: a -> Value) {-# INLINE toValue #-} -- | Instance derived using 'genericFromArray' instance (Generic a, GFromArray (Rep a)) => FromValue (GenericTomlArray a) where fromValue :: forall l. Value' l -> Matcher l (GenericTomlArray a) fromValue = coerce (genericFromArray :: Value' l -> Matcher l a) {-# INLINE fromValue #-}