{-| Module : Config.Lens Description : Lenses and traversals for manipulating 'Value' values. Copyright : (c) Eric Mertens, 2017 License : ISC Maintainer : emertens@gmail.com Lenses and traversals for compatibility with the lens package -} module Config.Lens ( key , text , atom , number , list , values , sections , ann , valuePlate ) where import Config.Number import Config.Value import Data.Text -- | Traversal for the subsections of the given 'Value' when -- that value is a 'Sections' and the section name matches the -- given name. key :: Applicative f => Text {- ^ section name -} -> (Value a -> f (Value a)) -> Value a -> f (Value a) key i = sections . traverse . section i -- | Traversal for the 'Value' contained inside the given -- 'Section' when its section name matches the given name. section :: Applicative f => Text {- ^ section name -} -> (Value a -> f (Value a)) -> Section a -> f (Section a) section i f s@(Section a j v) | i == j = Section a j <$> f v | otherwise = pure s -- | Traversal for the ['Section'] contained inside the given -- 'Value' when it is a 'Sections'. sections :: Applicative f => ([Section a] -> f [Section a]) -> Value a -> f (Value a) sections f (Sections a xs) = Sections a <$> f xs sections _ v = pure v -- | Traversal for the 'Text' contained inside the given 'Value'. text :: Applicative f => (Text -> f Text) -> Value a -> f (Value a) text f (Text a t) = Text a <$> f t text _ v = pure v -- | Traversal for the 'Atom' contained inside the given 'Value'. atom :: Applicative f => (Atom -> f Atom) -> Value a -> f (Value a) atom f (Atom a t) = Atom a <$> f t atom _ v = pure v -- | Traversal for the 'Number' contained inside the given 'Value'. number :: Applicative f => (Number -> f Number) -> Value a -> f (Value a) number f (Number a n) = Number a <$> f n number _ v = pure v -- | Traversal for the ['Value'] contained inside the given -- 'Value' when it is a 'List'. list :: Applicative f => ([Value a] -> f [Value a]) -> Value a -> f (Value a) list f (List a xs) = List a <$> f xs list _ v = pure v -- | Traversal for the immediate values in a list or a sections list. -- -- This is intended to be used with "Control.Lens.Plated". valuePlate :: Applicative f => (Value a -> f (Value a)) -> Value a -> f (Value a) valuePlate f (List a xs) = List a <$> traverse f xs valuePlate f (Sections a xs) = Sections a <$> traverse (sectionVal f) xs valuePlate _ v = pure v sectionVal :: Functor f => (Value a -> f (Value a)) -> Section a -> f (Section a) sectionVal f (Section a k v) = Section a k <$> f v -- | Traversal for the 'Value' elements inside the given -- 'Value' when it is a 'List'. -- -- @ -- 'values' = 'list' . 'traverse' -- @ values :: Applicative f => (Value a -> f (Value a)) -> Value a -> f (Value a) values = list . traverse -- | Lens for the annotation component of a 'Value' ann :: Functor f => (a -> f a) -> Value a -> f (Value a) ann f v = case v of Sections a x -> (\a' -> Sections a' x) <$> f a Number a x -> (\a' -> Number a' x) <$> f a Text a x -> (\a' -> Text a' x) <$> f a Atom a x -> (\a' -> Atom a' x) <$> f a List a x -> (\a' -> List a' x) <$> f a