{-# LANGUAGE DeriveFoldable         #-}
{-# LANGUAGE DeriveFunctor          #-}
{-# LANGUAGE DeriveTraversable      #-}
{-# LANGUAGE FlexibleContexts       #-}
{-# LANGUAGE FlexibleInstances      #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses  #-}
{-# LANGUAGE NoImplicitPrelude      #-}
{-# LANGUAGE TupleSections          #-}
-- |
--
-- Data structures and functions for handling the elements contained in a 'Waargonaut.Types.CommaSep.CommaSeparated' structure.
--
module Waargonaut.Types.CommaSep.Elems
  (
    -- * Types
    Elems (..)
  , HasElems (..)

    -- * Parse
  , parseCommaSeparatedElems

    -- * Functions
  , consElems
  , unconsElems
  ) where

import           Prelude                        (Eq, Show)

import           Control.Applicative            (Applicative (..), liftA2, pure,
                                                 (<*>))
import           Control.Category               (id, (.))
import           Control.Monad                  (Monad)

import           Control.Lens                   (Lens', cons, from, snoc, to,
                                                 (%~), (.~), (^.), (^?), _Cons)

import           Data.Bifoldable                (Bifoldable (bifoldMap))
import           Data.Bifunctor                 (Bifunctor (bimap))
import           Data.Bitraversable             (Bitraversable (bitraverse))
import           Data.Foldable                  (Foldable, foldMap)
import           Data.Function                  (($), (&))
import           Data.Functor                   (Functor, fmap, (<$>))
import           Data.Functor.Identity          (Identity (..))
import           Data.Maybe                     (Maybe (..), maybe)
import           Data.Monoid                    (Monoid (..), mempty)
import           Data.Semigroup                 (Semigroup ((<>)))
import           Data.Traversable               (Traversable, traverse)

import           Data.Vector                    (Vector)

import           Text.Parser.Char               (CharParsing)
import qualified Text.Parser.Combinators        as C

import           Waargonaut.Types.CommaSep.Elem (Comma, Elem (..), HasElem (..),
                                                 parseCommaTrailingMaybe,
                                                 _ElemTrailingIso)
-- $setup
-- >>> :set -XOverloadedStrings
-- >>> import Utils
-- >>> import Waargonaut.Types.Json
-- >>> import Waargonaut.Types.Whitespace
-- >>> import Control.Monad (return)
-- >>> import Data.Either (Either (..), isLeft)
-- >>> import Waargonaut.Decode.Error (DecodeError)
-- >>> import Data.Digit (HeXDigit)
-- >>> import Text.Parser.Char (alphaNum)
-- >>> import Data.Char (Char)
-- >>> let charWS = ((,) <$> alphaNum <*> parseWhitespace) :: CharParsing f => f (Char, WS)
----

-- | This type represents a non-empty list of elements, enforcing that the any
-- element but the last must be followed by a trailing comma and supporting option
-- of a final trailing comma.
data Elems ws a = Elems
  { Elems ws a -> Vector (Elem Identity ws a)
_elemsElems :: Vector (Elem Identity ws a)
  , Elems ws a -> Elem Maybe ws a
_elemsLast  :: Elem Maybe ws a
  }
  deriving (Elems ws a -> Elems ws a -> Bool
(Elems ws a -> Elems ws a -> Bool)
-> (Elems ws a -> Elems ws a -> Bool) -> Eq (Elems ws a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall ws a. (Eq ws, Eq a) => Elems ws a -> Elems ws a -> Bool
/= :: Elems ws a -> Elems ws a -> Bool
$c/= :: forall ws a. (Eq ws, Eq a) => Elems ws a -> Elems ws a -> Bool
== :: Elems ws a -> Elems ws a -> Bool
$c== :: forall ws a. (Eq ws, Eq a) => Elems ws a -> Elems ws a -> Bool
Eq, Int -> Elems ws a -> ShowS
[Elems ws a] -> ShowS
Elems ws a -> String
(Int -> Elems ws a -> ShowS)
-> (Elems ws a -> String)
-> ([Elems ws a] -> ShowS)
-> Show (Elems ws a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall ws a. (Show ws, Show a) => Int -> Elems ws a -> ShowS
forall ws a. (Show ws, Show a) => [Elems ws a] -> ShowS
forall ws a. (Show ws, Show a) => Elems ws a -> String
showList :: [Elems ws a] -> ShowS
$cshowList :: forall ws a. (Show ws, Show a) => [Elems ws a] -> ShowS
show :: Elems ws a -> String
$cshow :: forall ws a. (Show ws, Show a) => Elems ws a -> String
showsPrec :: Int -> Elems ws a -> ShowS
$cshowsPrec :: forall ws a. (Show ws, Show a) => Int -> Elems ws a -> ShowS
Show, a -> Elems ws b -> Elems ws a
(a -> b) -> Elems ws a -> Elems ws b
(forall a b. (a -> b) -> Elems ws a -> Elems ws b)
-> (forall a b. a -> Elems ws b -> Elems ws a)
-> Functor (Elems ws)
forall a b. a -> Elems ws b -> Elems ws a
forall a b. (a -> b) -> Elems ws a -> Elems ws b
forall ws a b. a -> Elems ws b -> Elems ws a
forall ws a b. (a -> b) -> Elems ws a -> Elems ws b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Elems ws b -> Elems ws a
$c<$ :: forall ws a b. a -> Elems ws b -> Elems ws a
fmap :: (a -> b) -> Elems ws a -> Elems ws b
$cfmap :: forall ws a b. (a -> b) -> Elems ws a -> Elems ws b
Functor, Elems ws a -> Bool
(a -> m) -> Elems ws a -> m
(a -> b -> b) -> b -> Elems ws a -> b
(forall m. Monoid m => Elems ws m -> m)
-> (forall m a. Monoid m => (a -> m) -> Elems ws a -> m)
-> (forall m a. Monoid m => (a -> m) -> Elems ws a -> m)
-> (forall a b. (a -> b -> b) -> b -> Elems ws a -> b)
-> (forall a b. (a -> b -> b) -> b -> Elems ws a -> b)
-> (forall b a. (b -> a -> b) -> b -> Elems ws a -> b)
-> (forall b a. (b -> a -> b) -> b -> Elems ws a -> b)
-> (forall a. (a -> a -> a) -> Elems ws a -> a)
-> (forall a. (a -> a -> a) -> Elems ws a -> a)
-> (forall a. Elems ws a -> [a])
-> (forall a. Elems ws a -> Bool)
-> (forall a. Elems ws a -> Int)
-> (forall a. Eq a => a -> Elems ws a -> Bool)
-> (forall a. Ord a => Elems ws a -> a)
-> (forall a. Ord a => Elems ws a -> a)
-> (forall a. Num a => Elems ws a -> a)
-> (forall a. Num a => Elems ws a -> a)
-> Foldable (Elems ws)
forall a. Eq a => a -> Elems ws a -> Bool
forall a. Num a => Elems ws a -> a
forall a. Ord a => Elems ws a -> a
forall m. Monoid m => Elems ws m -> m
forall a. Elems ws a -> Bool
forall a. Elems ws a -> Int
forall a. Elems ws a -> [a]
forall a. (a -> a -> a) -> Elems ws a -> a
forall ws a. Eq a => a -> Elems ws a -> Bool
forall ws a. Num a => Elems ws a -> a
forall ws a. Ord a => Elems ws a -> a
forall m a. Monoid m => (a -> m) -> Elems ws a -> m
forall ws m. Monoid m => Elems ws m -> m
forall ws a. Elems ws a -> Bool
forall ws a. Elems ws a -> Int
forall ws a. Elems ws a -> [a]
forall b a. (b -> a -> b) -> b -> Elems ws a -> b
forall a b. (a -> b -> b) -> b -> Elems ws a -> b
forall ws a. (a -> a -> a) -> Elems ws a -> a
forall ws m a. Monoid m => (a -> m) -> Elems ws a -> m
forall ws b a. (b -> a -> b) -> b -> Elems ws a -> b
forall ws a b. (a -> b -> b) -> b -> Elems ws a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: Elems ws a -> a
$cproduct :: forall ws a. Num a => Elems ws a -> a
sum :: Elems ws a -> a
$csum :: forall ws a. Num a => Elems ws a -> a
minimum :: Elems ws a -> a
$cminimum :: forall ws a. Ord a => Elems ws a -> a
maximum :: Elems ws a -> a
$cmaximum :: forall ws a. Ord a => Elems ws a -> a
elem :: a -> Elems ws a -> Bool
$celem :: forall ws a. Eq a => a -> Elems ws a -> Bool
length :: Elems ws a -> Int
$clength :: forall ws a. Elems ws a -> Int
null :: Elems ws a -> Bool
$cnull :: forall ws a. Elems ws a -> Bool
toList :: Elems ws a -> [a]
$ctoList :: forall ws a. Elems ws a -> [a]
foldl1 :: (a -> a -> a) -> Elems ws a -> a
$cfoldl1 :: forall ws a. (a -> a -> a) -> Elems ws a -> a
foldr1 :: (a -> a -> a) -> Elems ws a -> a
$cfoldr1 :: forall ws a. (a -> a -> a) -> Elems ws a -> a
foldl' :: (b -> a -> b) -> b -> Elems ws a -> b
$cfoldl' :: forall ws b a. (b -> a -> b) -> b -> Elems ws a -> b
foldl :: (b -> a -> b) -> b -> Elems ws a -> b
$cfoldl :: forall ws b a. (b -> a -> b) -> b -> Elems ws a -> b
foldr' :: (a -> b -> b) -> b -> Elems ws a -> b
$cfoldr' :: forall ws a b. (a -> b -> b) -> b -> Elems ws a -> b
foldr :: (a -> b -> b) -> b -> Elems ws a -> b
$cfoldr :: forall ws a b. (a -> b -> b) -> b -> Elems ws a -> b
foldMap' :: (a -> m) -> Elems ws a -> m
$cfoldMap' :: forall ws m a. Monoid m => (a -> m) -> Elems ws a -> m
foldMap :: (a -> m) -> Elems ws a -> m
$cfoldMap :: forall ws m a. Monoid m => (a -> m) -> Elems ws a -> m
fold :: Elems ws m -> m
$cfold :: forall ws m. Monoid m => Elems ws m -> m
Foldable, Functor (Elems ws)
Foldable (Elems ws)
Functor (Elems ws)
-> Foldable (Elems ws)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> Elems ws a -> f (Elems ws b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Elems ws (f a) -> f (Elems ws a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Elems ws a -> m (Elems ws b))
-> (forall (m :: * -> *) a.
    Monad m =>
    Elems ws (m a) -> m (Elems ws a))
-> Traversable (Elems ws)
(a -> f b) -> Elems ws a -> f (Elems ws b)
forall ws. Functor (Elems ws)
forall ws. Foldable (Elems ws)
forall ws (m :: * -> *) a.
Monad m =>
Elems ws (m a) -> m (Elems ws a)
forall ws (f :: * -> *) a.
Applicative f =>
Elems ws (f a) -> f (Elems ws a)
forall ws (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Elems ws a -> m (Elems ws b)
forall ws (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Elems ws a -> f (Elems ws b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Elems ws (m a) -> m (Elems ws a)
forall (f :: * -> *) a.
Applicative f =>
Elems ws (f a) -> f (Elems ws a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Elems ws a -> m (Elems ws b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Elems ws a -> f (Elems ws b)
sequence :: Elems ws (m a) -> m (Elems ws a)
$csequence :: forall ws (m :: * -> *) a.
Monad m =>
Elems ws (m a) -> m (Elems ws a)
mapM :: (a -> m b) -> Elems ws a -> m (Elems ws b)
$cmapM :: forall ws (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Elems ws a -> m (Elems ws b)
sequenceA :: Elems ws (f a) -> f (Elems ws a)
$csequenceA :: forall ws (f :: * -> *) a.
Applicative f =>
Elems ws (f a) -> f (Elems ws a)
traverse :: (a -> f b) -> Elems ws a -> f (Elems ws b)
$ctraverse :: forall ws (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Elems ws a -> f (Elems ws b)
$cp2Traversable :: forall ws. Foldable (Elems ws)
$cp1Traversable :: forall ws. Functor (Elems ws)
Traversable)

instance Bifunctor Elems where
  bimap :: (a -> b) -> (c -> d) -> Elems a c -> Elems b d
bimap a -> b
f c -> d
g (Elems Vector (Elem Identity a c)
es Elem Maybe a c
el) = Vector (Elem Identity b d) -> Elem Maybe b d -> Elems b d
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems ((Elem Identity a c -> Elem Identity b d)
-> Vector (Elem Identity a c) -> Vector (Elem Identity b d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (c -> d) -> Elem Identity a c -> Elem Identity b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f c -> d
g) Vector (Elem Identity a c)
es) ((a -> b) -> (c -> d) -> Elem Maybe a c -> Elem Maybe b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap a -> b
f c -> d
g Elem Maybe a c
el)

instance Bifoldable Elems where
  bifoldMap :: (a -> m) -> (b -> m) -> Elems a b -> m
bifoldMap a -> m
f b -> m
g (Elems Vector (Elem Identity a b)
es Elem Maybe a b
el) = (Elem Identity a b -> m) -> Vector (Elem Identity a b) -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((a -> m) -> (b -> m) -> Elem Identity a b -> m
forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap a -> m
f b -> m
g) Vector (Elem Identity a b)
es m -> m -> m
forall a. Monoid a => a -> a -> a
`mappend` (a -> m) -> (b -> m) -> Elem Maybe a b -> m
forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap a -> m
f b -> m
g Elem Maybe a b
el

instance Bitraversable Elems where
  bitraverse :: (a -> f c) -> (b -> f d) -> Elems a b -> f (Elems c d)
bitraverse a -> f c
f b -> f d
g (Elems Vector (Elem Identity a b)
es Elem Maybe a b
el) = Vector (Elem Identity c d) -> Elem Maybe c d -> Elems c d
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems
    (Vector (Elem Identity c d) -> Elem Maybe c d -> Elems c d)
-> f (Vector (Elem Identity c d))
-> f (Elem Maybe c d -> Elems c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Elem Identity a b -> f (Elem Identity c d))
-> Vector (Elem Identity a b) -> f (Vector (Elem Identity c d))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((a -> f c)
-> (b -> f d) -> Elem Identity a b -> f (Elem Identity c d)
forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse a -> f c
f b -> f d
g) Vector (Elem Identity a b)
es
    f (Elem Maybe c d -> Elems c d)
-> f (Elem Maybe c d) -> f (Elems c d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> f c) -> (b -> f d) -> Elem Maybe a b -> f (Elem Maybe c d)
forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse a -> f c
f b -> f d
g Elem Maybe a b
el

-- | Typeclass for things that contain an 'Elems' structure.
class HasElems c ws a | c -> ws a where
  elems      :: Lens' c (Elems ws a)
  elemsElems :: Lens' c (Vector (Elem Identity ws a))
  {-# INLINE elemsElems #-}
  elemsLast  :: Lens' c (Elem Maybe ws a)
  {-# INLINE elemsLast #-}
  elemsElems = (Elems ws a -> f (Elems ws a)) -> c -> f c
forall c ws a. HasElems c ws a => Lens' c (Elems ws a)
elems ((Elems ws a -> f (Elems ws a)) -> c -> f c)
-> ((Vector (Elem Identity ws a)
     -> f (Vector (Elem Identity ws a)))
    -> Elems ws a -> f (Elems ws a))
-> (Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
-> c
-> f c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
-> Elems ws a -> f (Elems ws a)
forall c ws a.
HasElems c ws a =>
Lens' c (Vector (Elem Identity ws a))
elemsElems
  elemsLast  = (Elems ws a -> f (Elems ws a)) -> c -> f c
forall c ws a. HasElems c ws a => Lens' c (Elems ws a)
elems ((Elems ws a -> f (Elems ws a)) -> c -> f c)
-> ((Elem Maybe ws a -> f (Elem Maybe ws a))
    -> Elems ws a -> f (Elems ws a))
-> (Elem Maybe ws a -> f (Elem Maybe ws a))
-> c
-> f c
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Elem Maybe ws a -> f (Elem Maybe ws a))
-> Elems ws a -> f (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast

instance HasElems (Elems ws a) ws a where
  {-# INLINE elemsElems #-}
  {-# INLINE elemsLast #-}
  elems :: (Elems ws a -> f (Elems ws a)) -> Elems ws a -> f (Elems ws a)
elems = (Elems ws a -> f (Elems ws a)) -> Elems ws a -> f (Elems ws a)
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  elemsElems :: (Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
-> Elems ws a -> f (Elems ws a)
elemsElems Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a))
f (Elems Vector (Elem Identity ws a)
x1 Elem Maybe ws a
x2) = (Vector (Elem Identity ws a) -> Elems ws a)
-> f (Vector (Elem Identity ws a)) -> f (Elems ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
`Elems` Elem Maybe ws a
x2) (Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a))
f Vector (Elem Identity ws a)
x1)
  elemsLast :: (Elem Maybe ws a -> f (Elem Maybe ws a))
-> Elems ws a -> f (Elems ws a)
elemsLast Elem Maybe ws a -> f (Elem Maybe ws a)
f (Elems Vector (Elem Identity ws a)
x1 Elem Maybe ws a
x2) = (Elem Maybe ws a -> Elems ws a)
-> f (Elem Maybe ws a) -> f (Elems ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems Vector (Elem Identity ws a)
x1) (Elem Maybe ws a -> f (Elem Maybe ws a)
f Elem Maybe ws a
x2)

instance Monoid ws => Applicative (Elems ws) where
  pure :: a -> Elems ws a
pure a
a = Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems Vector (Elem Identity ws a)
forall a. Monoid a => a
mempty (a -> Elem Maybe ws a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)
  Elems Vector (Elem Identity ws (a -> b))
atobs Elem Maybe ws (a -> b)
atob <*> :: Elems ws (a -> b) -> Elems ws a -> Elems ws b
<*> Elems Vector (Elem Identity ws a)
as Elem Maybe ws a
a = Vector (Elem Identity ws b) -> Elem Maybe ws b -> Elems ws b
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems ((Elem Identity ws (a -> b)
 -> Elem Identity ws a -> Elem Identity ws b)
-> Vector (Elem Identity ws (a -> b))
-> Vector (Elem Identity ws a)
-> Vector (Elem Identity ws b)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Elem Identity ws (a -> b)
-> Elem Identity ws a -> Elem Identity ws b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>) Vector (Elem Identity ws (a -> b))
atobs Vector (Elem Identity ws a)
as) (Elem Maybe ws (a -> b)
atob Elem Maybe ws (a -> b) -> Elem Maybe ws a -> Elem Maybe ws b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Elem Maybe ws a
a)

instance Monoid ws => Semigroup (Elems ws a) where
  <> :: Elems ws a -> Elems ws a -> Elems ws a
(<>) (Elems Vector (Elem Identity ws a)
as Elem Maybe ws a
alast) (Elems Vector (Elem Identity ws a)
bs Elem Maybe ws a
blast) =
    Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems (Vector (Elem Identity ws a)
-> Elem Identity ws a -> Vector (Elem Identity ws a)
forall s a. Snoc s s a a => s -> a -> s
snoc Vector (Elem Identity ws a)
as (Elem Maybe ws a
alast Elem Maybe ws a
-> Getting
     (Elem Identity ws a) (Elem Maybe ws a) (Elem Identity ws a)
-> Elem Identity ws a
forall s a. s -> Getting a s a -> a
^. AnIso
  (Elem Identity ws a)
  (Elem Identity ws a)
  (Elem Maybe ws a)
  (Elem Maybe ws a)
-> Iso
     (Elem Maybe ws a)
     (Elem Maybe ws a)
     (Elem Identity ws a)
     (Elem Identity ws a)
forall s t a b. AnIso s t a b -> Iso b a t s
from AnIso
  (Elem Identity ws a)
  (Elem Identity ws a)
  (Elem Maybe ws a)
  (Elem Maybe ws a)
forall ws ws' a a'.
(Monoid ws, Monoid ws') =>
Iso
  (Elem Identity ws a)
  (Elem Identity ws' a')
  (Elem Maybe ws a)
  (Elem Maybe ws' a')
_ElemTrailingIso) Vector (Elem Identity ws a)
-> Vector (Elem Identity ws a) -> Vector (Elem Identity ws a)
forall a. Semigroup a => a -> a -> a
<> Vector (Elem Identity ws a)
bs) Elem Maybe ws a
blast

-- | Add a value to the beginning of the 'Elems'
consElems :: Monoid ws => ((Comma,ws), a) -> Elems ws a -> Elems ws a
consElems :: ((Comma, ws), a) -> Elems ws a -> Elems ws a
consElems ((Comma, ws)
ews,a
a) Elems ws a
e = Elems ws a
e Elems ws a -> (Elems ws a -> Elems ws a) -> Elems ws a
forall a b. a -> (a -> b) -> b
& (Vector (Elem Identity ws a)
 -> Identity (Vector (Elem Identity ws a)))
-> Elems ws a -> Identity (Elems ws a)
forall c ws a.
HasElems c ws a =>
Lens' c (Vector (Elem Identity ws a))
elemsElems ((Vector (Elem Identity ws a)
  -> Identity (Vector (Elem Identity ws a)))
 -> Elems ws a -> Identity (Elems ws a))
-> (Vector (Elem Identity ws a) -> Vector (Elem Identity ws a))
-> Elems ws a
-> Elems ws a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ Elem Identity ws a
-> Vector (Elem Identity ws a) -> Vector (Elem Identity ws a)
forall s a. Cons s s a a => a -> s -> s
cons (a -> Identity (Comma, ws) -> Elem Identity ws a
forall (f :: * -> *) ws a. a -> f (Comma, ws) -> Elem f ws a
Elem a
a ((Comma, ws) -> Identity (Comma, ws)
forall a. a -> Identity a
Identity (Comma, ws)
ews))
{-# INLINE consElems #-}

-- | Attempt to remove the initial value off the front of an 'Elems'
unconsElems :: Monoid ws => Elems ws a -> ((Maybe (Comma,ws), a), Maybe (Elems ws a))
unconsElems :: Elems ws a -> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
unconsElems Elems ws a
e = ((Maybe (Comma, ws), a), Maybe (Elems ws a))
-> ((Elem Identity ws a, Vector (Elem Identity ws a))
    -> ((Maybe (Comma, ws), a), Maybe (Elems ws a)))
-> Maybe (Elem Identity ws a, Vector (Elem Identity ws a))
-> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ((Maybe (Comma, ws), a)
e', Maybe (Elems ws a)
forall a. Maybe a
Nothing) (\(Elem Identity ws a
em, Vector (Elem Identity ws a)
ems) -> (Elem Identity ws a -> (Maybe (Comma, ws), a)
forall s ws b.
HasElem s Identity ws b =>
s -> (Maybe (Comma, ws), b)
idT Elem Identity ws a
em, Elems ws a -> Maybe (Elems ws a)
forall a. a -> Maybe a
Just (Elems ws a -> Maybe (Elems ws a))
-> Elems ws a -> Maybe (Elems ws a)
forall a b. (a -> b) -> a -> b
$ Elems ws a
e Elems ws a -> (Elems ws a -> Elems ws a) -> Elems ws a
forall a b. a -> (a -> b) -> b
& (Vector (Elem Identity ws a)
 -> Identity (Vector (Elem Identity ws a)))
-> Elems ws a -> Identity (Elems ws a)
forall c ws a.
HasElems c ws a =>
Lens' c (Vector (Elem Identity ws a))
elemsElems ((Vector (Elem Identity ws a)
  -> Identity (Vector (Elem Identity ws a)))
 -> Elems ws a -> Identity (Elems ws a))
-> Vector (Elem Identity ws a) -> Elems ws a -> Elems ws a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Vector (Elem Identity ws a)
ems)) Maybe (Elem Identity ws a, Vector (Elem Identity ws a))
es'
  where
    es' :: Maybe (Elem Identity ws a, Vector (Elem Identity ws a))
es'   = Elems ws a
e Elems ws a
-> Getting
     (First (Elem Identity ws a, Vector (Elem Identity ws a)))
     (Elems ws a)
     (Elem Identity ws a, Vector (Elem Identity ws a))
-> Maybe (Elem Identity ws a, Vector (Elem Identity ws a))
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Vector (Elem Identity ws a)
 -> Const
      (First (Elem Identity ws a, Vector (Elem Identity ws a)))
      (Vector (Elem Identity ws a)))
-> Elems ws a
-> Const
     (First (Elem Identity ws a, Vector (Elem Identity ws a)))
     (Elems ws a)
forall c ws a.
HasElems c ws a =>
Lens' c (Vector (Elem Identity ws a))
elemsElems ((Vector (Elem Identity ws a)
  -> Const
       (First (Elem Identity ws a, Vector (Elem Identity ws a)))
       (Vector (Elem Identity ws a)))
 -> Elems ws a
 -> Const
      (First (Elem Identity ws a, Vector (Elem Identity ws a)))
      (Elems ws a))
-> (((Elem Identity ws a, Vector (Elem Identity ws a))
     -> Const
          (First (Elem Identity ws a, Vector (Elem Identity ws a)))
          (Elem Identity ws a, Vector (Elem Identity ws a)))
    -> Vector (Elem Identity ws a)
    -> Const
         (First (Elem Identity ws a, Vector (Elem Identity ws a)))
         (Vector (Elem Identity ws a)))
-> Getting
     (First (Elem Identity ws a, Vector (Elem Identity ws a)))
     (Elems ws a)
     (Elem Identity ws a, Vector (Elem Identity ws a))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Elem Identity ws a, Vector (Elem Identity ws a))
 -> Const
      (First (Elem Identity ws a, Vector (Elem Identity ws a)))
      (Elem Identity ws a, Vector (Elem Identity ws a)))
-> Vector (Elem Identity ws a)
-> Const
     (First (Elem Identity ws a, Vector (Elem Identity ws a)))
     (Vector (Elem Identity ws a))
forall s t a b. Cons s t a b => Prism s t (a, s) (b, t)
_Cons
    e' :: (Maybe (Comma, ws), a)
e'    = (Elems ws a
e Elems ws a
-> Getting (Maybe (Comma, ws)) (Elems ws a) (Maybe (Comma, ws))
-> Maybe (Comma, ws)
forall s a. s -> Getting a s a -> a
^. (Elem Maybe ws a -> Const (Maybe (Comma, ws)) (Elem Maybe ws a))
-> Elems ws a -> Const (Maybe (Comma, ws)) (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast ((Elem Maybe ws a -> Const (Maybe (Comma, ws)) (Elem Maybe ws a))
 -> Elems ws a -> Const (Maybe (Comma, ws)) (Elems ws a))
-> ((Maybe (Comma, ws)
     -> Const (Maybe (Comma, ws)) (Maybe (Comma, ws)))
    -> Elem Maybe ws a -> Const (Maybe (Comma, ws)) (Elem Maybe ws a))
-> Getting (Maybe (Comma, ws)) (Elems ws a) (Maybe (Comma, ws))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Maybe (Comma, ws)
 -> Const (Maybe (Comma, ws)) (Maybe (Comma, ws)))
-> Elem Maybe ws a -> Const (Maybe (Comma, ws)) (Elem Maybe ws a)
forall c (f :: * -> *) ws a.
HasElem c f ws a =>
Lens' c (f (Comma, ws))
elemTrailing, Elems ws a
e Elems ws a -> Getting a (Elems ws a) a -> a
forall s a. s -> Getting a s a -> a
^. (Elem Maybe ws a -> Const a (Elem Maybe ws a))
-> Elems ws a -> Const a (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast ((Elem Maybe ws a -> Const a (Elem Maybe ws a))
 -> Elems ws a -> Const a (Elems ws a))
-> ((a -> Const a a)
    -> Elem Maybe ws a -> Const a (Elem Maybe ws a))
-> Getting a (Elems ws a) a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a -> Const a a) -> Elem Maybe ws a -> Const a (Elem Maybe ws a)
forall c (f :: * -> *) ws a. HasElem c f ws a => Lens' c a
elemVal)
    idT :: s -> (Maybe (Comma, ws), b)
idT s
x = (s
x s
-> Getting (Maybe (Comma, ws)) s (Maybe (Comma, ws))
-> Maybe (Comma, ws)
forall s a. s -> Getting a s a -> a
^. (Identity (Comma, ws)
 -> Const (Maybe (Comma, ws)) (Identity (Comma, ws)))
-> s -> Const (Maybe (Comma, ws)) s
forall c (f :: * -> *) ws a.
HasElem c f ws a =>
Lens' c (f (Comma, ws))
elemTrailing ((Identity (Comma, ws)
  -> Const (Maybe (Comma, ws)) (Identity (Comma, ws)))
 -> s -> Const (Maybe (Comma, ws)) s)
-> ((Maybe (Comma, ws)
     -> Const (Maybe (Comma, ws)) (Maybe (Comma, ws)))
    -> Identity (Comma, ws)
    -> Const (Maybe (Comma, ws)) (Identity (Comma, ws)))
-> Getting (Maybe (Comma, ws)) s (Maybe (Comma, ws))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Identity (Comma, ws) -> Maybe (Comma, ws))
-> (Maybe (Comma, ws)
    -> Const (Maybe (Comma, ws)) (Maybe (Comma, ws)))
-> Identity (Comma, ws)
-> Const (Maybe (Comma, ws)) (Identity (Comma, ws))
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to ((Comma, ws) -> Maybe (Comma, ws)
forall a. a -> Maybe a
Just ((Comma, ws) -> Maybe (Comma, ws))
-> (Identity (Comma, ws) -> (Comma, ws))
-> Identity (Comma, ws)
-> Maybe (Comma, ws)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Identity (Comma, ws) -> (Comma, ws)
forall a. Identity a -> a
runIdentity), s
x s -> Getting b s b -> b
forall s a. s -> Getting a s a -> a
^. Getting b s b
forall c (f :: * -> *) ws a. HasElem c f ws a => Lens' c a
elemVal)
{-# INLINE unconsElems #-}

-- | Parse the elements of a 'Waargonaut.Types.CommaSep.CommaSeparated' list, handling the optional trailing comma and its whitespace.
--
-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b, c, d"
-- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Nothing}})
--
-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "a, b,c,d, "
-- Right (Elems {_elemsElems = [Elem {_elemVal = 'a', _elemTrailing = Identity (Comma,WS [Space])},Elem {_elemVal = 'b', _elemTrailing = Identity (Comma,WS [])},Elem {_elemVal = 'c', _elemTrailing = Identity (Comma,WS [])}], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})
--
-- >>> testparse (parseCommaSeparatedElems parseWhitespace alphaNum) "d, "
-- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = 'd', _elemTrailing = Just (Comma,WS [Space])}})
--
-- >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d , "
-- Right (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = ('d',WS [Space]), _elemTrailing = Just (Comma,WS [Space])}})
--
-- >>> testparse (parseCommaSeparatedElems parseWhitespace charWS) "d\n, e,  "
-- Right (Elems {_elemsElems = [Elem {_elemVal = ('d',WS [NewLine]), _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = ('e',WS []), _elemTrailing = Just (Comma,WS [Space,Space])}})
--
parseCommaSeparatedElems
  :: ( Monad f
     , CharParsing f
     )
  => f ws
  -> f a
  -> f (Elems ws a)
parseCommaSeparatedElems :: f ws -> f a -> f (Elems ws a)
parseCommaSeparatedElems f ws
ws f a
a = do
  a
hd <- f a
a
  Maybe (Comma, ws)
sep <- f ws -> f (Maybe (Comma, ws))
forall (f :: * -> *) ws.
CharParsing f =>
f ws -> f (Maybe (Comma, ws))
parseCommaTrailingMaybe f ws
ws
  f (Elems ws a)
-> ((Comma, ws) -> f (Elems ws a))
-> Maybe (Comma, ws)
-> f (Elems ws a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Elems ws a -> f (Elems ws a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Elems ws a -> f (Elems ws a)) -> Elems ws a -> f (Elems ws a)
forall a b. (a -> b) -> a -> b
$ Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems Vector (Elem Identity ws a)
forall a. Monoid a => a
mempty (a -> Maybe (Comma, ws) -> Elem Maybe ws a
forall (f :: * -> *) ws a. a -> f (Comma, ws) -> Elem f ws a
Elem a
hd Maybe (Comma, ws)
sep)) (Vector (Elem Identity ws a) -> (a, (Comma, ws)) -> f (Elems ws a)
go Vector (Elem Identity ws a)
forall a. Monoid a => a
mempty ((a, (Comma, ws)) -> f (Elems ws a))
-> ((Comma, ws) -> (a, (Comma, ws)))
-> (Comma, ws)
-> f (Elems ws a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a
hd,)) Maybe (Comma, ws)
sep
  where
    idElem :: a -> (Comma, ws) -> Elem Identity ws a
idElem a
e = a -> Identity (Comma, ws) -> Elem Identity ws a
forall (f :: * -> *) ws a. a -> f (Comma, ws) -> Elem f ws a
Elem a
e (Identity (Comma, ws) -> Elem Identity ws a)
-> ((Comma, ws) -> Identity (Comma, ws))
-> (Comma, ws)
-> Elem Identity ws a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Comma, ws) -> Identity (Comma, ws)
forall a. a -> Identity a
Identity

    fin :: Vector (Elem Identity ws a)
-> a -> Maybe (Comma, ws) -> f (Elems ws a)
fin Vector (Elem Identity ws a)
cels a
lj Maybe (Comma, ws)
sp =
      Elems ws a -> f (Elems ws a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Elems ws a -> f (Elems ws a)) -> Elems ws a -> f (Elems ws a)
forall a b. (a -> b) -> a -> b
$ Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
forall ws a.
Vector (Elem Identity ws a) -> Elem Maybe ws a -> Elems ws a
Elems Vector (Elem Identity ws a)
cels (a -> Maybe (Comma, ws) -> Elem Maybe ws a
forall (f :: * -> *) ws a. a -> f (Comma, ws) -> Elem f ws a
Elem a
lj Maybe (Comma, ws)
sp)

    go :: Vector (Elem Identity ws a) -> (a, (Comma, ws)) -> f (Elems ws a)
go Vector (Elem Identity ws a)
commaElems (a
lastJ, (Comma, ws)
lastSep) = do
      Maybe a
mJ <- f a -> f (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional f a
a
      case Maybe a
mJ of
        Maybe a
Nothing -> Vector (Elem Identity ws a)
-> a -> Maybe (Comma, ws) -> f (Elems ws a)
forall (f :: * -> *) ws a.
Applicative f =>
Vector (Elem Identity ws a)
-> a -> Maybe (Comma, ws) -> f (Elems ws a)
fin Vector (Elem Identity ws a)
commaElems a
lastJ ((Comma, ws) -> Maybe (Comma, ws)
forall a. a -> Maybe a
Just (Comma, ws)
lastSep)
        Just a
j -> do
          Maybe (Comma, ws)
msep <- f ws -> f (Maybe (Comma, ws))
forall (f :: * -> *) ws.
CharParsing f =>
f ws -> f (Maybe (Comma, ws))
parseCommaTrailingMaybe f ws
ws
          let commaElems' :: Vector (Elem Identity ws a)
commaElems' = Vector (Elem Identity ws a)
-> Elem Identity ws a -> Vector (Elem Identity ws a)
forall s a. Snoc s s a a => s -> a -> s
snoc Vector (Elem Identity ws a)
commaElems (Elem Identity ws a -> Vector (Elem Identity ws a))
-> Elem Identity ws a -> Vector (Elem Identity ws a)
forall a b. (a -> b) -> a -> b
$ a -> (Comma, ws) -> Elem Identity ws a
forall a ws. a -> (Comma, ws) -> Elem Identity ws a
idElem a
lastJ (Comma, ws)
lastSep
          f (Elems ws a)
-> ((Comma, ws) -> f (Elems ws a))
-> Maybe (Comma, ws)
-> f (Elems ws a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Vector (Elem Identity ws a)
-> a -> Maybe (Comma, ws) -> f (Elems ws a)
forall (f :: * -> *) ws a.
Applicative f =>
Vector (Elem Identity ws a)
-> a -> Maybe (Comma, ws) -> f (Elems ws a)
fin Vector (Elem Identity ws a)
commaElems' a
j Maybe (Comma, ws)
forall a. Maybe a
Nothing) (Vector (Elem Identity ws a) -> (a, (Comma, ws)) -> f (Elems ws a)
go Vector (Elem Identity ws a)
commaElems' ((a, (Comma, ws)) -> f (Elems ws a))
-> ((Comma, ws) -> (a, (Comma, ws)))
-> (Comma, ws)
-> f (Elems ws a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (a
j,)) Maybe (Comma, ws)
msep