module Data.Sv.Syntax.Field (
Field (Unquoted, Quoted)
, SpacedField
, Spaced (Spaced)
, HasFields (fields)
, AsField (_Field, _Unquoted, _Quoted)
, unescapedField
, foldField
, fieldContents
) where
import Control.DeepSeq (NFData)
import Control.Lens (Lens, Prism', Traversal, lens, prism)
import Data.Foldable (Foldable (foldMap))
import Data.Functor (Functor (fmap))
import Data.Traversable (Traversable (traverse))
import GHC.Generics (Generic)
import Text.Escape (Unescaped (Unescaped, getRawUnescaped))
import Text.Quote (Quote)
import Text.Space (Spaced (Spaced))
data Field s =
Unquoted s
| Quoted Quote (Unescaped s)
deriving (Eq, Ord, Show, Generic)
instance NFData s => NFData (Field s)
instance Functor Field where
fmap f fi = case fi of
Unquoted s -> Unquoted (f s)
Quoted q v -> Quoted q (fmap f v)
instance Foldable Field where
foldMap f fi = case fi of
Unquoted s -> f s
Quoted _ v -> foldMap f v
instance Traversable Field where
traverse f fi = case fi of
Unquoted s -> Unquoted <$> f s
Quoted q v -> Quoted q <$> traverse f v
type SpacedField a = Spaced (Field a)
class (HasFields s s a a) => AsField s a | s -> a where
_Field :: Prism' s (Field a)
_Unquoted :: Prism' s a
_Quoted :: Prism' s (Quote, Unescaped a)
_Unquoted = _Field . _Unquoted
_Quoted = _Field . _Quoted
instance AsField (Field a) a where
_Field = id
_Unquoted = prism Unquoted
(\x -> case x of
Unquoted y -> Right y
_ -> Left x
)
_Quoted = prism (uncurry Quoted)
(\x -> case x of
Quoted y z -> Right (y,z)
_ -> Left x
)
class HasFields c d s t | c -> s, d -> t, c t -> d, d s -> c where
fields :: Traversal c d (Field s) (Field t)
instance HasFields (Field s) (Field t) s t where
fields = id
unescapedField :: Quote -> s -> Field s
unescapedField q s = Quoted q (Unescaped s)
foldField :: (s -> b) -> (Quote -> Unescaped s -> b) -> Field s -> b
foldField u q fi = case fi of
Unquoted s -> u s
Quoted a b -> q a b
fieldContents :: Lens (Field s) (Field t) s t
fieldContents =
lens (foldField id (const getRawUnescaped)) $ \f b -> case f of
Unquoted _ -> Unquoted b
Quoted q _ -> Quoted q (Unescaped b)