    {-|
    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 :: forall (f :: * -> *) a.
    Applicative f =>
    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)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [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 :: forall (f :: * -> *) a.
    Applicative f =>
    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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    ([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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    (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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    (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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    (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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    ([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 a. a -> f 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 :: forall (f :: * -> *) a.
    Applicative f =>
    (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)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [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)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [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 a. a -> f 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 :: forall (f :: * -> *) a.
    Functor f =>
    (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 :: forall (f :: * -> *) a.
    Applicative f =>
    (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)
    forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> [a] -> f [b]
    traverse

    -- | Lens for the annotation component of a 'Value'
    ann :: Functor f => (a -> f a) -> Value a -> f (Value a)
    ann :: forall (f :: * -> *) a.
    Functor f =>
    (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