{-|
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 :: Text -> (Value a -> f (Value a)) -> Value a -> f (Value a)
key Text
i = ([Section a] -> f [Section a]) -> Value a -> f (Value a)
forall (f :: * -> *) a.
Applicative f =>
([Section a] -> f [Section a]) -> Value a -> f (Value a)
sections (([Section a] -> f [Section a]) -> Value a -> f (Value a))
-> ((Value a -> f (Value a)) -> [Section a] -> f [Section a])
-> (Value a -> f (Value a))
-> Value a
-> f (Value a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Section a -> f (Section a)) -> [Section a] -> f [Section a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Section a -> f (Section a)) -> [Section a] -> f [Section a])
-> ((Value a -> f (Value a)) -> Section a -> f (Section a))
-> (Value a -> f (Value a))
-> [Section a]
-> f [Section a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> (Value a -> f (Value a)) -> Section a -> f (Section a)
forall (f :: * -> *) a.
Applicative f =>
Text -> (Value a -> f (Value a)) -> Section a -> f (Section a)
section Text
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 :: Text -> (Value a -> f (Value a)) -> Section a -> f (Section a)
section Text
i Value a -> f (Value a)
f s :: Section a
s@(Section a
a Text
j Value a
v) | Text
i Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
j    = a -> Text -> Value a -> Section a
forall a. a -> Text -> Value a -> Section a
Section a
a Text
j (Value a -> Section a) -> f (Value a) -> f (Section a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value a -> f (Value a)
f Value a
v
                              | Bool
otherwise = Section a -> f (Section a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Section a
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 :: ([Section a] -> f [Section a]) -> Value a -> f (Value a)
sections [Section a] -> f [Section a]
f (Sections a
a [Section a]
xs) = a -> [Section a] -> Value a
forall a. a -> [Section a] -> Value a
Sections a
a ([Section a] -> Value a) -> f [Section a] -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Section a] -> f [Section a]
f [Section a]
xs
sections [Section a] -> f [Section a]
_ Value a
v               = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
v

-- | Traversal for the 'Text' contained inside the given 'Value'.
text :: Applicative f => (Text -> f Text) -> Value a -> f (Value a)
text :: (Text -> f Text) -> Value a -> f (Value a)
text Text -> f Text
f (Text a
a Text
t) = a -> Text -> Value a
forall a. a -> Text -> Value a
Text a
a (Text -> Value a) -> f Text -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> f Text
f Text
t
text Text -> f Text
_ Value a
v          = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
v

-- | Traversal for the 'Atom' contained inside the given 'Value'.
atom :: Applicative f => (Atom -> f Atom) -> Value a -> f (Value a)
atom :: (Atom -> f Atom) -> Value a -> f (Value a)
atom Atom -> f Atom
f (Atom a
a Atom
t) = a -> Atom -> Value a
forall a. a -> Atom -> Value a
Atom a
a (Atom -> Value a) -> f Atom -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Atom -> f Atom
f Atom
t
atom Atom -> f Atom
_ Value a
v          = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
v

-- | Traversal for the 'Number' contained inside the given 'Value'.
number :: Applicative f => (Number -> f Number) -> Value a -> f (Value a)
number :: (Number -> f Number) -> Value a -> f (Value a)
number Number -> f Number
f (Number a
a Number
n) = a -> Number -> Value a
forall a. a -> Number -> Value a
Number a
a (Number -> Value a) -> f Number -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Number -> f Number
f Number
n
number Number -> f Number
_ Value a
v            = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
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 :: ([Value a] -> f [Value a]) -> Value a -> f (Value a)
list [Value a] -> f [Value a]
f (List a
a [Value a]
xs) = a -> [Value a] -> Value a
forall a. a -> [Value a] -> Value a
List a
a ([Value a] -> Value a) -> f [Value a] -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Value a] -> f [Value a]
f [Value a]
xs
list [Value a] -> f [Value a]
_ Value a
v           = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
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 :: (Value a -> f (Value a)) -> Value a -> f (Value a)
valuePlate Value a -> f (Value a)
f (List     a
a [Value a]
xs) = a -> [Value a] -> Value a
forall a. a -> [Value a] -> Value a
List     a
a ([Value a] -> Value a) -> f [Value a] -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Value a -> f (Value a)) -> [Value a] -> f [Value a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse             Value a -> f (Value a)
f  [Value a]
xs
valuePlate Value a -> f (Value a)
f (Sections a
a [Section a]
xs) = a -> [Section a] -> Value a
forall a. a -> [Section a] -> Value a
Sections a
a ([Section a] -> Value a) -> f [Section a] -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Section a -> f (Section a)) -> [Section a] -> f [Section a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Value a -> f (Value a)) -> Section a -> f (Section a)
forall (f :: * -> *) a.
Functor f =>
(Value a -> f (Value a)) -> Section a -> f (Section a)
sectionVal Value a -> f (Value a)
f) [Section a]
xs
valuePlate Value a -> f (Value a)
_ Value a
v               = Value a -> f (Value a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Value a
v

sectionVal :: Functor f => (Value a -> f (Value a)) -> Section a -> f (Section a)
sectionVal :: (Value a -> f (Value a)) -> Section a -> f (Section a)
sectionVal Value a -> f (Value a)
f (Section a
a Text
k Value a
v) = a -> Text -> Value a -> Section a
forall a. a -> Text -> Value a -> Section a
Section a
a Text
k (Value a -> Section a) -> f (Value a) -> f (Section a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value a -> f (Value a)
f Value a
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 :: (Value a -> f (Value a)) -> Value a -> f (Value a)
values = ([Value a] -> f [Value a]) -> Value a -> f (Value a)
forall (f :: * -> *) a.
Applicative f =>
([Value a] -> f [Value a]) -> Value a -> f (Value a)
list (([Value a] -> f [Value a]) -> Value a -> f (Value a))
-> ((Value a -> f (Value a)) -> [Value a] -> f [Value a])
-> (Value a -> f (Value a))
-> Value a
-> f (Value a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value a -> f (Value a)) -> [Value a] -> f [Value a]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse


-- | Lens for the annotation component of a 'Value'
ann :: Functor f => (a -> f a) -> Value a -> f (Value a)
ann :: (a -> f a) -> Value a -> f (Value a)
ann a -> f a
f Value a
v =
  case Value a
v of
    Sections a
a [Section a]
x -> (\a
a' -> a -> [Section a] -> Value a
forall a. a -> [Section a] -> Value a
Sections a
a' [Section a]
x) (a -> Value a) -> f a -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
a
    Number   a
a Number
x -> (\a
a' -> a -> Number -> Value a
forall a. a -> Number -> Value a
Number   a
a' Number
x) (a -> Value a) -> f a -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
a
    Text     a
a Text
x -> (\a
a' -> a -> Text -> Value a
forall a. a -> Text -> Value a
Text     a
a' Text
x) (a -> Value a) -> f a -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
a
    Atom     a
a Atom
x -> (\a
a' -> a -> Atom -> Value a
forall a. a -> Atom -> Value a
Atom     a
a' Atom
x) (a -> Value a) -> f a -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
a
    List     a
a [Value a]
x -> (\a
a' -> a -> [Value a] -> Value a
forall a. a -> [Value a] -> Value a
List     a
a' [Value a]
x) (a -> Value a) -> f a -> f (Value a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f a
f a
a