{-# LANGUAGE DeriveFoldable        #-}
{-# LANGUAGE DeriveFunctor         #-}
{-# LANGUAGE DeriveTraversable     #-}
{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude     #-}
{-# LANGUAGE RankNTypes            #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeFamilies          #-}
-- | Both arrays and objects in JSON allow for an optional trailing comma on the
-- final element. This module houses the shared types and functions that let us
-- handle this.
module Waargonaut.Types.CommaSep
  (
    -- * Types
    CommaSeparated (..)
  , Elems (..)
  , HasElems (..)
  , Elem (..)
  , HasElem (..)
  , Comma (..)

    -- * Parse
  , parseComma
  , parseCommaSeparated

    -- * Conversion
  , _CommaSeparated
  , toList
  , fromList
  , fromCommaSep

    -- * Cons / Uncons
  , consCommaSep
  , unconsCommaSep
  ) where

import           Prelude                         (Eq, Int, Show, (&&), (==),
                                                  (||))

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

import           Control.Lens                    (AsEmpty (..), Cons (..), Traversal',
                                                  Index, Iso, IxValue,
                                                  Ixed (..), Snoc (..), cons,
                                                  from, iso, mapped, nearly, preview,
                                                  over, prism, snoc, to,
                                                  traverse, unsnoc, (%%~), (%~),
                                                  (.~), (^.), (^..), (^?), _1,
                                                  _2, _Cons, _Just, _Nothing)
import           Control.Lens.Extras             (is)

import           Control.Error.Util              (note)
import           Control.Monad                   (Monad)

import           Data.Bifoldable                 (Bifoldable (bifoldMap))
import           Data.Bifunctor                  (Bifunctor (bimap))
import           Data.Bitraversable              (Bitraversable (bitraverse))
import           Data.Either                     (Either (..))
import           Data.Foldable                   (Foldable, asum, foldMap,
                                                  foldr, length)
import           Data.Function                   (flip, ($), (&))
import           Data.Functor                    (Functor, fmap, (<$), (<$>))
import           Data.Maybe                      (Maybe (..), maybe)
import           Data.Monoid                     (Monoid (..), mempty)
import           Data.Semigroup                  (Semigroup ((<>)))
import           Data.Traversable                (Traversable)
import           Data.Tuple                      (uncurry)

import qualified Data.Vector                     as V

import           Text.Parser.Char                (CharParsing)

import           Data.Witherable                 (Filterable (..),
                                                  Witherable (..))

import           Waargonaut.Types.CommaSep.Elem  (Comma (..), Elem (..),
                                                  HasElem (..), parseComma,
                                                  _ElemTrailingIso)

import           Waargonaut.Types.CommaSep.Elems (Elems (..), HasElems (..),
                                                  consElems,
                                                  parseCommaSeparatedElems,
                                                  unconsElems)

-- $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 Data.Char (Char)
-- >>> import Text.Parser.Char (alphaNum, char)
-- >>> let charWS = ((,) <$> alphaNum <*> parseWhitespace) :: CharParsing f => f (Char, WS)
----

-- | This type is our possibly empty comma-separated list of values. It carries
-- information about any leading whitespace before the first element, as well as a
-- the rest of the elements in an 'Elems' type.
data CommaSeparated ws a = CommaSeparated ws (Maybe (Elems ws a))
  deriving (CommaSeparated ws a -> CommaSeparated ws a -> Bool
(CommaSeparated ws a -> CommaSeparated ws a -> Bool)
-> (CommaSeparated ws a -> CommaSeparated ws a -> Bool)
-> Eq (CommaSeparated ws a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall ws a.
(Eq ws, Eq a) =>
CommaSeparated ws a -> CommaSeparated ws a -> Bool
/= :: CommaSeparated ws a -> CommaSeparated ws a -> Bool
$c/= :: forall ws a.
(Eq ws, Eq a) =>
CommaSeparated ws a -> CommaSeparated ws a -> Bool
== :: CommaSeparated ws a -> CommaSeparated ws a -> Bool
$c== :: forall ws a.
(Eq ws, Eq a) =>
CommaSeparated ws a -> CommaSeparated ws a -> Bool
Eq, Int -> CommaSeparated ws a -> ShowS
[CommaSeparated ws a] -> ShowS
CommaSeparated ws a -> String
(Int -> CommaSeparated ws a -> ShowS)
-> (CommaSeparated ws a -> String)
-> ([CommaSeparated ws a] -> ShowS)
-> Show (CommaSeparated ws a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall ws a.
(Show ws, Show a) =>
Int -> CommaSeparated ws a -> ShowS
forall ws a. (Show ws, Show a) => [CommaSeparated ws a] -> ShowS
forall ws a. (Show ws, Show a) => CommaSeparated ws a -> String
showList :: [CommaSeparated ws a] -> ShowS
$cshowList :: forall ws a. (Show ws, Show a) => [CommaSeparated ws a] -> ShowS
show :: CommaSeparated ws a -> String
$cshow :: forall ws a. (Show ws, Show a) => CommaSeparated ws a -> String
showsPrec :: Int -> CommaSeparated ws a -> ShowS
$cshowsPrec :: forall ws a.
(Show ws, Show a) =>
Int -> CommaSeparated ws a -> ShowS
Show, a -> CommaSeparated ws b -> CommaSeparated ws a
(a -> b) -> CommaSeparated ws a -> CommaSeparated ws b
(forall a b.
 (a -> b) -> CommaSeparated ws a -> CommaSeparated ws b)
-> (forall a b. a -> CommaSeparated ws b -> CommaSeparated ws a)
-> Functor (CommaSeparated ws)
forall a b. a -> CommaSeparated ws b -> CommaSeparated ws a
forall a b. (a -> b) -> CommaSeparated ws a -> CommaSeparated ws b
forall ws a b. a -> CommaSeparated ws b -> CommaSeparated ws a
forall ws a b.
(a -> b) -> CommaSeparated ws a -> CommaSeparated ws b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> CommaSeparated ws b -> CommaSeparated ws a
$c<$ :: forall ws a b. a -> CommaSeparated ws b -> CommaSeparated ws a
fmap :: (a -> b) -> CommaSeparated ws a -> CommaSeparated ws b
$cfmap :: forall ws a b.
(a -> b) -> CommaSeparated ws a -> CommaSeparated ws b
Functor, CommaSeparated ws a -> Bool
(a -> m) -> CommaSeparated ws a -> m
(a -> b -> b) -> b -> CommaSeparated ws a -> b
(forall m. Monoid m => CommaSeparated ws m -> m)
-> (forall m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m)
-> (forall m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m)
-> (forall a b. (a -> b -> b) -> b -> CommaSeparated ws a -> b)
-> (forall a b. (a -> b -> b) -> b -> CommaSeparated ws a -> b)
-> (forall b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b)
-> (forall b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b)
-> (forall a. (a -> a -> a) -> CommaSeparated ws a -> a)
-> (forall a. (a -> a -> a) -> CommaSeparated ws a -> a)
-> (forall a. CommaSeparated ws a -> [a])
-> (forall a. CommaSeparated ws a -> Bool)
-> (forall a. CommaSeparated ws a -> Int)
-> (forall a. Eq a => a -> CommaSeparated ws a -> Bool)
-> (forall a. Ord a => CommaSeparated ws a -> a)
-> (forall a. Ord a => CommaSeparated ws a -> a)
-> (forall a. Num a => CommaSeparated ws a -> a)
-> (forall a. Num a => CommaSeparated ws a -> a)
-> Foldable (CommaSeparated ws)
forall a. Eq a => a -> CommaSeparated ws a -> Bool
forall a. Num a => CommaSeparated ws a -> a
forall a. Ord a => CommaSeparated ws a -> a
forall m. Monoid m => CommaSeparated ws m -> m
forall a. CommaSeparated ws a -> Bool
forall a. CommaSeparated ws a -> Int
forall a. CommaSeparated ws a -> [a]
forall a. (a -> a -> a) -> CommaSeparated ws a -> a
forall ws a. Eq a => a -> CommaSeparated ws a -> Bool
forall ws a. Num a => CommaSeparated ws a -> a
forall ws a. Ord a => CommaSeparated ws a -> a
forall m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m
forall ws m. Monoid m => CommaSeparated ws m -> m
forall ws a. CommaSeparated ws a -> Bool
forall ws a. CommaSeparated ws a -> Int
forall ws a. CommaSeparated ws a -> [a]
forall b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b
forall a b. (a -> b -> b) -> b -> CommaSeparated ws a -> b
forall ws a. (a -> a -> a) -> CommaSeparated ws a -> a
forall ws m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m
forall ws b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b
forall ws a b. (a -> b -> b) -> b -> CommaSeparated 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 :: CommaSeparated ws a -> a
$cproduct :: forall ws a. Num a => CommaSeparated ws a -> a
sum :: CommaSeparated ws a -> a
$csum :: forall ws a. Num a => CommaSeparated ws a -> a
minimum :: CommaSeparated ws a -> a
$cminimum :: forall ws a. Ord a => CommaSeparated ws a -> a
maximum :: CommaSeparated ws a -> a
$cmaximum :: forall ws a. Ord a => CommaSeparated ws a -> a
elem :: a -> CommaSeparated ws a -> Bool
$celem :: forall ws a. Eq a => a -> CommaSeparated ws a -> Bool
length :: CommaSeparated ws a -> Int
$clength :: forall ws a. CommaSeparated ws a -> Int
null :: CommaSeparated ws a -> Bool
$cnull :: forall ws a. CommaSeparated ws a -> Bool
toList :: CommaSeparated ws a -> [a]
$ctoList :: forall ws a. CommaSeparated ws a -> [a]
foldl1 :: (a -> a -> a) -> CommaSeparated ws a -> a
$cfoldl1 :: forall ws a. (a -> a -> a) -> CommaSeparated ws a -> a
foldr1 :: (a -> a -> a) -> CommaSeparated ws a -> a
$cfoldr1 :: forall ws a. (a -> a -> a) -> CommaSeparated ws a -> a
foldl' :: (b -> a -> b) -> b -> CommaSeparated ws a -> b
$cfoldl' :: forall ws b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b
foldl :: (b -> a -> b) -> b -> CommaSeparated ws a -> b
$cfoldl :: forall ws b a. (b -> a -> b) -> b -> CommaSeparated ws a -> b
foldr' :: (a -> b -> b) -> b -> CommaSeparated ws a -> b
$cfoldr' :: forall ws a b. (a -> b -> b) -> b -> CommaSeparated ws a -> b
foldr :: (a -> b -> b) -> b -> CommaSeparated ws a -> b
$cfoldr :: forall ws a b. (a -> b -> b) -> b -> CommaSeparated ws a -> b
foldMap' :: (a -> m) -> CommaSeparated ws a -> m
$cfoldMap' :: forall ws m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m
foldMap :: (a -> m) -> CommaSeparated ws a -> m
$cfoldMap :: forall ws m a. Monoid m => (a -> m) -> CommaSeparated ws a -> m
fold :: CommaSeparated ws m -> m
$cfold :: forall ws m. Monoid m => CommaSeparated ws m -> m
Foldable, Functor (CommaSeparated ws)
Foldable (CommaSeparated ws)
Functor (CommaSeparated ws)
-> Foldable (CommaSeparated ws)
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> CommaSeparated ws a -> f (CommaSeparated ws b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    CommaSeparated ws (f a) -> f (CommaSeparated ws a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> CommaSeparated ws a -> m (CommaSeparated ws b))
-> (forall (m :: * -> *) a.
    Monad m =>
    CommaSeparated ws (m a) -> m (CommaSeparated ws a))
-> Traversable (CommaSeparated ws)
(a -> f b) -> CommaSeparated ws a -> f (CommaSeparated ws b)
forall ws. Functor (CommaSeparated ws)
forall ws. Foldable (CommaSeparated ws)
forall ws (m :: * -> *) a.
Monad m =>
CommaSeparated ws (m a) -> m (CommaSeparated ws a)
forall ws (f :: * -> *) a.
Applicative f =>
CommaSeparated ws (f a) -> f (CommaSeparated ws a)
forall ws (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommaSeparated ws a -> m (CommaSeparated ws b)
forall ws (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommaSeparated ws a -> f (CommaSeparated 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 =>
CommaSeparated ws (m a) -> m (CommaSeparated ws a)
forall (f :: * -> *) a.
Applicative f =>
CommaSeparated ws (f a) -> f (CommaSeparated ws a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommaSeparated ws a -> m (CommaSeparated ws b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommaSeparated ws a -> f (CommaSeparated ws b)
sequence :: CommaSeparated ws (m a) -> m (CommaSeparated ws a)
$csequence :: forall ws (m :: * -> *) a.
Monad m =>
CommaSeparated ws (m a) -> m (CommaSeparated ws a)
mapM :: (a -> m b) -> CommaSeparated ws a -> m (CommaSeparated ws b)
$cmapM :: forall ws (m :: * -> *) a b.
Monad m =>
(a -> m b) -> CommaSeparated ws a -> m (CommaSeparated ws b)
sequenceA :: CommaSeparated ws (f a) -> f (CommaSeparated ws a)
$csequenceA :: forall ws (f :: * -> *) a.
Applicative f =>
CommaSeparated ws (f a) -> f (CommaSeparated ws a)
traverse :: (a -> f b) -> CommaSeparated ws a -> f (CommaSeparated ws b)
$ctraverse :: forall ws (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> CommaSeparated ws a -> f (CommaSeparated ws b)
$cp2Traversable :: forall ws. Foldable (CommaSeparated ws)
$cp1Traversable :: forall ws. Functor (CommaSeparated ws)
Traversable)

instance Bifunctor CommaSeparated where
  bimap :: (a -> b) -> (c -> d) -> CommaSeparated a c -> CommaSeparated b d
bimap a -> b
f c -> d
g (CommaSeparated a
ws Maybe (Elems a c)
c) = b -> Maybe (Elems b d) -> CommaSeparated b d
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated (a -> b
f a
ws) ((Elems a c -> Elems b d) -> Maybe (Elems a c) -> Maybe (Elems b d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> b) -> (c -> d) -> Elems a c -> Elems 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) Maybe (Elems a c)
c)

instance Bifoldable CommaSeparated where
  bifoldMap :: (a -> m) -> (b -> m) -> CommaSeparated a b -> m
bifoldMap a -> m
f b -> m
g (CommaSeparated a
ws Maybe (Elems a b)
c) = a -> m
f a
ws m -> m -> m
forall a. Monoid a => a -> a -> a
`mappend` (Elems a b -> m) -> Maybe (Elems a b) -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((a -> m) -> (b -> m) -> Elems 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) Maybe (Elems a b)
c

instance Bitraversable CommaSeparated where
  bitraverse :: (a -> f c)
-> (b -> f d) -> CommaSeparated a b -> f (CommaSeparated c d)
bitraverse a -> f c
f b -> f d
g (CommaSeparated a
ws Maybe (Elems a b)
c) = c -> Maybe (Elems c d) -> CommaSeparated c d
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated (c -> Maybe (Elems c d) -> CommaSeparated c d)
-> f c -> f (Maybe (Elems c d) -> CommaSeparated c d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f c
f a
ws f (Maybe (Elems c d) -> CommaSeparated c d)
-> f (Maybe (Elems c d)) -> f (CommaSeparated c d)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Elems a b -> f (Elems c d))
-> Maybe (Elems a b) -> f (Maybe (Elems 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) -> Elems a b -> f (Elems 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) Maybe (Elems a b)
c

-- | By ignoring whitespace we're able to write a 'Cons' instance.
instance Monoid ws => Cons (CommaSeparated ws a) (CommaSeparated ws a) a a where
  _Cons :: p (a, CommaSeparated ws a) (f (a, CommaSeparated ws a))
-> p (CommaSeparated ws a) (f (CommaSeparated ws a))
_Cons = ((a, CommaSeparated ws a) -> CommaSeparated ws a)
-> (CommaSeparated ws a
    -> Either (CommaSeparated ws a) (a, CommaSeparated ws a))
-> Prism
     (CommaSeparated ws a)
     (CommaSeparated ws a)
     (a, CommaSeparated ws a)
     (a, CommaSeparated ws a)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism
          (\(a
a,CommaSeparated ws a
cs) -> ((Comma, ws), a) -> CommaSeparated ws a -> CommaSeparated ws a
forall ws a.
Monoid ws =>
((Comma, ws), a) -> CommaSeparated ws a -> CommaSeparated ws a
consCommaSep ((Comma
Comma,ws
forall a. Monoid a => a
mempty), a
a) CommaSeparated ws a
cs)
          (\CommaSeparated ws a
c -> CommaSeparated ws a
-> Maybe (a, CommaSeparated ws a)
-> Either (CommaSeparated ws a) (a, CommaSeparated ws a)
forall a b. a -> Maybe b -> Either a b
note CommaSeparated ws a
c (Maybe (a, CommaSeparated ws a)
 -> Either (CommaSeparated ws a) (a, CommaSeparated ws a))
-> (Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
    -> Maybe (a, CommaSeparated ws a))
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
-> Either (CommaSeparated ws a) (a, CommaSeparated ws a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ASetter
  (Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a))
  (Maybe (a, CommaSeparated ws a))
  (Maybe (Comma, ws), a)
  a
-> ((Maybe (Comma, ws), a) -> a)
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
-> Maybe (a, CommaSeparated ws a)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ((((Maybe (Comma, ws), a), CommaSeparated ws a)
 -> Identity (a, CommaSeparated ws a))
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
-> Identity (Maybe (a, CommaSeparated ws a))
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
mapped ((((Maybe (Comma, ws), a), CommaSeparated ws a)
  -> Identity (a, CommaSeparated ws a))
 -> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
 -> Identity (Maybe (a, CommaSeparated ws a)))
-> (((Maybe (Comma, ws), a) -> Identity a)
    -> ((Maybe (Comma, ws), a), CommaSeparated ws a)
    -> Identity (a, CommaSeparated ws a))
-> ASetter
     (Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a))
     (Maybe (a, CommaSeparated ws a))
     (Maybe (Comma, 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
. ((Maybe (Comma, ws), a) -> Identity a)
-> ((Maybe (Comma, ws), a), CommaSeparated ws a)
-> Identity (a, CommaSeparated ws a)
forall s t a b. Field1 s t a b => Lens s t a b
_1) ((Maybe (Comma, ws), a) -> Getting a (Maybe (Comma, ws), a) a -> a
forall s a. s -> Getting a s a -> a
^. Getting a (Maybe (Comma, ws), a) a
forall s t a b. Field2 s t a b => Lens s t a b
_2) (Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
 -> Either (CommaSeparated ws a) (a, CommaSeparated ws a))
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
-> Either (CommaSeparated ws a) (a, CommaSeparated ws a)
forall a b. (a -> b) -> a -> b
$ CommaSeparated ws a
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
forall ws a.
Monoid ws =>
CommaSeparated ws a
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
unconsCommaSep CommaSeparated ws a
c)
  {-# INLINE _Cons #-}

instance Monoid ws => Snoc (CommaSeparated ws a) (CommaSeparated ws a) a a where
  _Snoc :: p (CommaSeparated ws a, a) (f (CommaSeparated ws a, a))
-> p (CommaSeparated ws a) (f (CommaSeparated ws a))
_Snoc = ((CommaSeparated ws a, a) -> CommaSeparated ws a)
-> (CommaSeparated ws a
    -> Either (CommaSeparated ws a) (CommaSeparated ws a, a))
-> Prism
     (CommaSeparated ws a)
     (CommaSeparated ws a)
     (CommaSeparated ws a, a)
     (CommaSeparated ws a, a)
forall b t s a. (b -> t) -> (s -> Either t a) -> Prism s t a b
prism (CommaSeparated ws a, a) -> CommaSeparated ws a
f CommaSeparated ws a
-> Either (CommaSeparated ws a) (CommaSeparated ws a, a)
g
    where
      f :: (CommaSeparated ws a, a) -> CommaSeparated ws a
      f :: (CommaSeparated ws a, a) -> CommaSeparated ws a
f (CommaSeparated ws a
cs,a
a) = ASetter
  (CommaSeparated ws a)
  (CommaSeparated ws a)
  (Elems ws a)
  (Elems ws a)
-> (Elems ws a -> Elems ws a)
-> CommaSeparated ws a
-> CommaSeparated ws a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (((ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
-> CommaSeparated ws a -> Identity (CommaSeparated ws a)
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
_CommaSeparated (((ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
 -> CommaSeparated ws a -> Identity (CommaSeparated ws a))
-> ((Elems ws a -> Identity (Elems ws a))
    -> (ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
-> ASetter
     (CommaSeparated ws a)
     (CommaSeparated ws a)
     (Elems ws a)
     (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
. (Maybe (Elems ws a) -> Identity (Maybe (Elems ws a)))
-> (ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a))
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((Maybe (Elems ws a) -> Identity (Maybe (Elems ws a)))
 -> (ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
-> ((Elems ws a -> Identity (Elems ws a))
    -> Maybe (Elems ws a) -> Identity (Maybe (Elems ws a)))
-> (Elems ws a -> Identity (Elems ws a))
-> (ws, Maybe (Elems ws a))
-> Identity (ws, Maybe (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
. (Elems ws a -> Identity (Elems ws a))
-> Maybe (Elems ws a) -> Identity (Maybe (Elems ws a))
forall a b. Prism (Maybe a) (Maybe b) a b
_Just)
        (\Elems ws a
es -> Elems ws a
es
          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
%~ (Vector (Elem Identity ws a)
 -> Elem Identity ws a -> Vector (Elem Identity ws a))
-> Elem Identity ws a
-> Vector (Elem Identity ws a)
-> Vector (Elem Identity ws a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip 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 (Elems ws a
es Elems ws a
-> Getting (Elem Identity ws a) (Elems ws a) (Elem Identity ws a)
-> Elem Identity ws a
forall s a. s -> Getting a s a -> a
^. (Elem Maybe ws a -> Const (Elem Identity ws a) (Elem Maybe ws a))
-> Elems ws a -> Const (Elem Identity ws a) (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast ((Elem Maybe ws a -> Const (Elem Identity ws a) (Elem Maybe ws a))
 -> Elems ws a -> Const (Elem Identity ws a) (Elems ws a))
-> ((Elem Identity ws a
     -> Const (Elem Identity ws a) (Elem Identity ws a))
    -> Elem Maybe ws a -> Const (Elem Identity ws a) (Elem Maybe ws a))
-> Getting (Elem Identity ws a) (Elems ws a) (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
. 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)
          Elems ws a -> (Elems ws a -> Elems ws a) -> Elems ws a
forall a b. a -> (a -> b) -> b
& (Elem Maybe ws a -> Identity (Elem Maybe ws a))
-> Elems ws a -> Identity (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast ((Elem Maybe ws a -> Identity (Elem Maybe ws a))
 -> Elems ws a -> Identity (Elems ws a))
-> ((a -> Identity a)
    -> Elem Maybe ws a -> Identity (Elem Maybe ws a))
-> (a -> Identity a)
-> Elems ws a
-> Identity (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 -> Identity a) -> Elem Maybe ws a -> Identity (Elem Maybe ws a)
forall c (f :: * -> *) ws a. HasElem c f ws a => Lens' c a
elemVal ((a -> Identity a) -> Elems ws a -> Identity (Elems ws a))
-> a -> Elems ws a -> Elems ws a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ a
a
        ) CommaSeparated ws a
cs

      g :: CommaSeparated ws a -> Either (CommaSeparated ws a) (CommaSeparated ws a, a)
      g :: CommaSeparated ws a
-> Either (CommaSeparated ws a) (CommaSeparated ws a, a)
g c :: CommaSeparated ws a
c@(CommaSeparated ws
_   Maybe (Elems ws a)
Nothing) = CommaSeparated ws a
-> Either (CommaSeparated ws a) (CommaSeparated ws a, a)
forall a b. a -> Either a b
Left CommaSeparated ws a
c
      g   (CommaSeparated ws
w (Just Elems ws a
es)) = (CommaSeparated ws a, a)
-> Either (CommaSeparated ws a) (CommaSeparated ws a, a)
forall a b. b -> Either a b
Right
        ( ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
w (Maybe (Elems ws a) -> CommaSeparated ws a)
-> Maybe (Elems ws a) -> CommaSeparated ws a
forall a b. (a -> b) -> a -> b
$ (Vector (Elem Identity ws a), Elem Identity ws a) -> Elems ws a
createNewElems ((Vector (Elem Identity ws a), Elem Identity ws a) -> Elems ws a)
-> Maybe (Vector (Elem Identity ws a), Elem Identity ws a)
-> Maybe (Elems ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Elems ws a
es Elems ws a
-> Getting
     (First (Vector (Elem Identity ws a), Elem Identity ws a))
     (Elems ws a)
     (Vector (Elem Identity ws a), Elem Identity ws a)
-> Maybe (Vector (Elem Identity ws a), Elem Identity ws a)
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Vector (Elem Identity ws a)
 -> Const
      (First (Vector (Elem Identity ws a), Elem Identity ws a))
      (Vector (Elem Identity ws a)))
-> Elems ws a
-> Const
     (First (Vector (Elem Identity ws a), 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 (Vector (Elem Identity ws a), Elem Identity ws a))
       (Vector (Elem Identity ws a)))
 -> Elems ws a
 -> Const
      (First (Vector (Elem Identity ws a), Elem Identity ws a))
      (Elems ws a))
-> (((Vector (Elem Identity ws a), Elem Identity ws a)
     -> Const
          (First (Vector (Elem Identity ws a), Elem Identity ws a))
          (Vector (Elem Identity ws a), Elem Identity ws a))
    -> Vector (Elem Identity ws a)
    -> Const
         (First (Vector (Elem Identity ws a), Elem Identity ws a))
         (Vector (Elem Identity ws a)))
-> Getting
     (First (Vector (Elem Identity ws a), Elem Identity ws a))
     (Elems ws a)
     (Vector (Elem Identity ws a), 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
. ((Vector (Elem Identity ws a), Elem Identity ws a)
 -> Const
      (First (Vector (Elem Identity ws a), Elem Identity ws a))
      (Vector (Elem Identity ws a), Elem Identity ws a))
-> Vector (Elem Identity ws a)
-> Const
     (First (Vector (Elem Identity ws a), Elem Identity ws a))
     (Vector (Elem Identity ws a))
forall s t a b. Snoc s t a b => Prism s t (s, a) (t, b)
_Snoc
        , Elems ws a
es 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
        )
        where
          createNewElems :: (Vector (Elem Identity ws a), Elem Identity ws a) -> Elems ws a
createNewElems (Vector (Elem Identity ws a)
newEs, Elem Identity ws a
newL) = Elems ws a
es
            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)
newEs
            Elems ws a -> (Elems ws a -> Elems ws a) -> Elems ws a
forall a b. a -> (a -> b) -> b
& (Elem Maybe ws a -> Identity (Elem Maybe ws a))
-> Elems ws a -> Identity (Elems ws a)
forall c ws a. HasElems c ws a => Lens' c (Elem Maybe ws a)
elemsLast ((Elem Maybe ws a -> Identity (Elem Maybe ws a))
 -> Elems ws a -> Identity (Elems ws a))
-> Elem Maybe ws a -> Elems ws a -> Elems ws a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Elem Identity ws a
newL Elem Identity ws a
-> Getting (Elem Maybe ws a) (Elem Identity ws a) (Elem Maybe ws a)
-> Elem Maybe ws a
forall s a. s -> Getting a s a -> a
^. Getting (Elem Maybe ws a) (Elem Identity 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

instance (Monoid ws, Semigroup ws) => Semigroup (CommaSeparated ws a) where
  (CommaSeparated ws
wsA Maybe (Elems ws a)
a) <> :: CommaSeparated ws a -> CommaSeparated ws a -> CommaSeparated ws a
<> (CommaSeparated ws
wsB Maybe (Elems ws a)
b) = ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated (ws
wsA ws -> ws -> ws
forall a. Semigroup a => a -> a -> a
<> ws
wsB) (Maybe (Elems ws a)
a Maybe (Elems ws a) -> Maybe (Elems ws a) -> Maybe (Elems ws a)
forall a. Semigroup a => a -> a -> a
<> Maybe (Elems ws a)
b)

instance (Monoid ws, Semigroup ws) => Monoid (CommaSeparated ws a) where
  mempty :: CommaSeparated ws a
mempty = ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
forall a. Monoid a => a
mempty Maybe (Elems ws a)
forall a. Maybe a
Nothing
  mappend :: CommaSeparated ws a -> CommaSeparated ws a -> CommaSeparated ws a
mappend = CommaSeparated ws a -> CommaSeparated ws a -> CommaSeparated ws a
forall a. Semigroup a => a -> a -> a
(<>)

instance Monoid ws => Filterable (CommaSeparated ws) where
  mapMaybe :: (a -> Maybe b) -> CommaSeparated ws a -> CommaSeparated ws b
mapMaybe a -> Maybe b
_ (CommaSeparated ws
ws Maybe (Elems ws a)
Nothing)              = ws -> Maybe (Elems ws b) -> CommaSeparated ws b
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
ws Maybe (Elems ws b)
forall a. Maybe a
Nothing
  mapMaybe a -> Maybe b
f (CommaSeparated ws
ws (Just (Elems Vector (Elem Identity ws a)
es Elem Maybe ws a
el))) = ws -> Maybe (Elems ws b) -> CommaSeparated ws b
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
ws Maybe (Elems ws b)
newElems
    where
      newElems :: Maybe (Elems ws b)
newElems = case (a -> Maybe b) -> Elem Maybe ws a -> Maybe (Elem Maybe ws b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> Maybe b
f Elem Maybe ws a
el of
        Maybe (Elem Maybe ws b)
Nothing -> (\(Vector (Elem Identity ws b)
v,Elem Identity ws b
l) -> 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 Vector (Elem Identity ws b)
v (Elem Identity ws b
l Elem Identity ws b
-> Getting (Elem Maybe ws b) (Elem Identity ws b) (Elem Maybe ws b)
-> Elem Maybe ws b
forall s a. s -> Getting a s a -> a
^. Getting (Elem Maybe ws b) (Elem Identity ws b) (Elem Maybe ws b)
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 b), Elem Identity ws b) -> Elems ws b)
-> Maybe (Vector (Elem Identity ws b), Elem Identity ws b)
-> Maybe (Elems ws b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector (Elem Identity ws b)
-> Maybe (Vector (Elem Identity ws b), Elem Identity ws b)
forall s a. Snoc s s a a => s -> Maybe (s, a)
unsnoc ((Elem Identity ws a -> Maybe (Elem Identity ws b))
-> Vector (Elem Identity ws a) -> Vector (Elem Identity ws b)
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe ((a -> Maybe b) -> Elem Identity ws a -> Maybe (Elem Identity ws b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> Maybe b
f) Vector (Elem Identity ws a)
es)
        Just Elem Maybe ws b
l' -> Elems ws b -> Maybe (Elems ws b)
forall a. a -> Maybe a
Just (Elems ws b -> Maybe (Elems ws b))
-> Elems ws b -> Maybe (Elems ws b)
forall a b. (a -> b) -> a -> b
$ 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 -> Maybe (Elem Identity ws b))
-> Vector (Elem Identity ws a) -> Vector (Elem Identity ws b)
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe ((a -> Maybe b) -> Elem Identity ws a -> Maybe (Elem Identity ws b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> Maybe b
f) Vector (Elem Identity ws a)
es) Elem Maybe ws b
l'

instance Monoid ws => Witherable (CommaSeparated ws) where

-- | Isomorphism between the internal pieces of a 'Waargonaut.Types.CommaSep.CommaSeparated' element.
_CommaSeparated :: Iso (CommaSeparated ws a) (CommaSeparated ws' b) (ws, Maybe (Elems ws a)) (ws', Maybe (Elems ws' b))
_CommaSeparated :: p (ws, Maybe (Elems ws a)) (f (ws', Maybe (Elems ws' b)))
-> p (CommaSeparated ws a) (f (CommaSeparated ws' b))
_CommaSeparated = (CommaSeparated ws a -> (ws, Maybe (Elems ws a)))
-> ((ws', Maybe (Elems ws' b)) -> CommaSeparated ws' b)
-> Iso
     (CommaSeparated ws a)
     (CommaSeparated ws' b)
     (ws, Maybe (Elems ws a))
     (ws', Maybe (Elems ws' b))
forall s a b t. (s -> a) -> (b -> t) -> Iso s t a b
iso (\(CommaSeparated ws
ws Maybe (Elems ws a)
a) -> (ws
ws,Maybe (Elems ws a)
a)) ((ws' -> Maybe (Elems ws' b) -> CommaSeparated ws' b)
-> (ws', Maybe (Elems ws' b)) -> CommaSeparated ws' b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ws' -> Maybe (Elems ws' b) -> CommaSeparated ws' b
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated)
{-# INLINE _CommaSeparated #-}

-- | Cons elements onto a 'Waargonaut.Types.CommaSep.CommaSeparated' with provided whitespace information.
-- If you don't need explicit whitespace then the 'Cons' instance is more straightforward.
consCommaSep :: Monoid ws => ((Comma,ws),a) -> CommaSeparated ws a -> CommaSeparated ws a
consCommaSep :: ((Comma, ws), a) -> CommaSeparated ws a -> CommaSeparated ws a
consCommaSep ((Comma, ws)
ews,a
a) = ASetter
  (CommaSeparated ws a)
  (CommaSeparated ws a)
  (Maybe (Elems ws a))
  (Maybe (Elems ws a))
-> (Maybe (Elems ws a) -> Maybe (Elems ws a))
-> CommaSeparated ws a
-> CommaSeparated ws a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over (((ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
-> CommaSeparated ws a -> Identity (CommaSeparated ws a)
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
_CommaSeparated (((ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
 -> CommaSeparated ws a -> Identity (CommaSeparated ws a))
-> ((Maybe (Elems ws a) -> Identity (Maybe (Elems ws a)))
    -> (ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a)))
-> ASetter
     (CommaSeparated ws a)
     (CommaSeparated ws a)
     (Maybe (Elems ws a))
     (Maybe (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
. (Maybe (Elems ws a) -> Identity (Maybe (Elems ws a)))
-> (ws, Maybe (Elems ws a)) -> Identity (ws, Maybe (Elems ws a))
forall s t a b. Field2 s t a b => Lens s t a b
_2) (Elems ws a -> Maybe (Elems ws a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Elems ws a -> Maybe (Elems ws a))
-> (Maybe (Elems ws a) -> Elems ws a)
-> Maybe (Elems ws a)
-> Maybe (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
. Elems ws a
-> (Elems ws a -> Elems ws a) -> Maybe (Elems ws a) -> Elems ws a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Elems ws a
new (((Comma, ws), a) -> Elems ws a -> Elems ws a
forall ws a.
Monoid ws =>
((Comma, ws), a) -> Elems ws a -> Elems ws a
consElems ((Comma, ws)
ews,a
a)))
  where new :: Elems ws a
new = 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
a Maybe (Comma, ws)
forall a. Maybe a
Nothing)
{-# INLINE consCommaSep #-}

-- | Attempt to "uncons" elements from the front of a 'Waargonaut.Types.CommaSep.CommaSeparated' without
-- discarding the elements' whitespace information. If you don't need explicit
-- whitespace then the 'Cons' instance is more straightforward.
unconsCommaSep :: Monoid ws => CommaSeparated ws a -> Maybe ((Maybe (Comma,ws), a), CommaSeparated ws a)
unconsCommaSep :: CommaSeparated ws a
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
unconsCommaSep (CommaSeparated ws
ws Maybe (Elems ws a)
es) = ASetter
  ((Maybe (Comma, ws), a), Maybe (Elems ws a))
  ((Maybe (Comma, ws), a), CommaSeparated ws a)
  (Maybe (Elems ws a))
  (CommaSeparated ws a)
-> (Maybe (Elems ws a) -> CommaSeparated ws a)
-> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
-> ((Maybe (Comma, ws), a), CommaSeparated ws a)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
over ASetter
  ((Maybe (Comma, ws), a), Maybe (Elems ws a))
  ((Maybe (Comma, ws), a), CommaSeparated ws a)
  (Maybe (Elems ws a))
  (CommaSeparated ws a)
forall s t a b. Field2 s t a b => Lens s t a b
_2 (ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
ws) (((Maybe (Comma, ws), a), Maybe (Elems ws a))
 -> ((Maybe (Comma, ws), a), CommaSeparated ws a))
-> (Elems ws a -> ((Maybe (Comma, ws), a), Maybe (Elems ws a)))
-> Elems ws a
-> ((Maybe (Comma, ws), a), CommaSeparated ws a)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Elems ws a -> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
forall ws a.
Monoid ws =>
Elems ws a -> ((Maybe (Comma, ws), a), Maybe (Elems ws a))
unconsElems (Elems ws a -> ((Maybe (Comma, ws), a), CommaSeparated ws a))
-> Maybe (Elems ws a)
-> Maybe ((Maybe (Comma, ws), a), CommaSeparated ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Elems ws a)
es
{-# INLINE unconsCommaSep #-}

instance (Semigroup ws, Monoid ws) => AsEmpty (CommaSeparated ws a) where
  _Empty :: p () (f ()) -> p (CommaSeparated ws a) (f (CommaSeparated ws a))
_Empty = CommaSeparated ws a
-> (CommaSeparated ws a -> Bool) -> Prism' (CommaSeparated ws a) ()
forall a. a -> (a -> Bool) -> Prism' a ()
nearly CommaSeparated ws a
forall a. Monoid a => a
mempty (CommaSeparated ws a
-> Getting Bool (CommaSeparated ws a) Bool -> Bool
forall s a. s -> Getting a s a -> a
^. ((ws, Maybe (Elems ws a)) -> Const Bool (ws, Maybe (Elems ws a)))
-> CommaSeparated ws a -> Const Bool (CommaSeparated ws a)
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
_CommaSeparated (((ws, Maybe (Elems ws a)) -> Const Bool (ws, Maybe (Elems ws a)))
 -> CommaSeparated ws a -> Const Bool (CommaSeparated ws a))
-> ((Bool -> Const Bool Bool)
    -> (ws, Maybe (Elems ws a)) -> Const Bool (ws, Maybe (Elems ws a)))
-> Getting Bool (CommaSeparated ws a) Bool
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Maybe (Elems ws a) -> Const Bool (Maybe (Elems ws a)))
-> (ws, Maybe (Elems ws a)) -> Const Bool (ws, Maybe (Elems ws a))
forall s t a b. Field2 s t a b => Lens s t a b
_2 ((Maybe (Elems ws a) -> Const Bool (Maybe (Elems ws a)))
 -> (ws, Maybe (Elems ws a)) -> Const Bool (ws, Maybe (Elems ws a)))
-> ((Bool -> Const Bool Bool)
    -> Maybe (Elems ws a) -> Const Bool (Maybe (Elems ws a)))
-> (Bool -> Const Bool Bool)
-> (ws, Maybe (Elems ws a))
-> Const Bool (ws, Maybe (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
. (Maybe (Elems ws a) -> Bool)
-> (Bool -> Const Bool Bool)
-> Maybe (Elems ws a)
-> Const Bool (Maybe (Elems ws a))
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to (APrism (Maybe (Elems ws a)) (Maybe (Elems ws a)) () ()
-> Maybe (Elems ws a) -> Bool
forall s t a b. APrism s t a b -> s -> Bool
is APrism (Maybe (Elems ws a)) (Maybe (Elems ws a)) () ()
forall a. Prism' (Maybe a) ()
_Nothing))

type instance IxValue (CommaSeparated ws a) = a
type instance Index (CommaSeparated ws a)   = Int

-- | Without a notion of "keys", this list can only be indexed by 'Int'
instance Ixed (CommaSeparated ws a) where

  ix :: Index (CommaSeparated ws a)
-> Traversal' (CommaSeparated ws a) (IxValue (CommaSeparated ws a))
ix Index (CommaSeparated ws a)
_ IxValue (CommaSeparated ws a) -> f (IxValue (CommaSeparated ws a))
_ c :: CommaSeparated ws a
c@(CommaSeparated ws
_ Maybe (Elems ws a)
Nothing) = CommaSeparated ws a -> f (CommaSeparated ws a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure CommaSeparated ws a
c

  ix Index (CommaSeparated ws a)
i IxValue (CommaSeparated ws a) -> f (IxValue (CommaSeparated ws a))
f (CommaSeparated ws
w (Just Elems ws a
es)) = ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated ws
w (Maybe (Elems ws a) -> CommaSeparated ws a)
-> (Elems ws a -> Maybe (Elems ws a))
-> Elems ws a
-> CommaSeparated ws a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Elems ws a -> Maybe (Elems ws a)
forall a. a -> Maybe a
Just (Elems ws a -> CommaSeparated ws a)
-> f (Elems ws a) -> f (CommaSeparated ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
    if Int
Index (CommaSeparated ws a)
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 Bool -> Bool -> Bool
&& Elems ws a
es Elems ws a -> Getting Bool (Elems ws a) Bool -> Bool
forall s a. s -> Getting a s a -> a
^. (Vector (Elem Identity ws a)
 -> Const Bool (Vector (Elem Identity ws a)))
-> Elems ws a -> Const Bool (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 Bool (Vector (Elem Identity ws a)))
 -> Elems ws a -> Const Bool (Elems ws a))
-> ((Bool -> Const Bool Bool)
    -> Vector (Elem Identity ws a)
    -> Const Bool (Vector (Elem Identity ws a)))
-> Getting Bool (Elems ws a) Bool
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) -> Bool)
-> (Bool -> Const Bool Bool)
-> Vector (Elem Identity ws a)
-> Const Bool (Vector (Elem Identity ws a))
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Vector (Elem Identity ws a) -> Bool
forall a. Vector a -> Bool
V.null Bool -> Bool -> Bool
|| Int
Index (CommaSeparated ws a)
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Elems ws a
es Elems ws a -> Getting Int (Elems ws a) Int -> Int
forall s a. s -> Getting a s a -> a
^. (Vector (Elem Identity ws a)
 -> Const Int (Vector (Elem Identity ws a)))
-> Elems ws a -> Const Int (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 Int (Vector (Elem Identity ws a)))
 -> Elems ws a -> Const Int (Elems ws a))
-> ((Int -> Const Int Int)
    -> Vector (Elem Identity ws a)
    -> Const Int (Vector (Elem Identity ws a)))
-> Getting Int (Elems ws a) Int
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) -> Int)
-> (Int -> Const Int Int)
-> Vector (Elem Identity ws a)
-> Const Int (Vector (Elem Identity ws a))
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to Vector (Elem Identity ws a) -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length
    then Elems ws a
es Elems ws a -> (Elems ws a -> f (Elems ws a)) -> f (Elems ws a)
forall a b. a -> (a -> b) -> b
& (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 ((Elem Maybe ws a -> f (Elem Maybe ws a))
 -> Elems ws a -> f (Elems ws a))
-> ((a -> f a) -> Elem Maybe ws a -> f (Elem Maybe ws a))
-> (a -> f a)
-> Elems ws a
-> 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 -> f a) -> Elem Maybe ws a -> f (Elem Maybe ws a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((a -> f a) -> Elems ws a -> f (Elems ws a))
-> (a -> f a) -> Elems ws a -> f (Elems ws a)
forall k (f :: k -> *) s (t :: k) a (b :: k).
LensLike f s t a b -> LensLike f s t a b
%%~ a -> f a
IxValue (CommaSeparated ws a) -> f (IxValue (CommaSeparated ws a))
f
    else Elems ws a
es Elems ws a -> (Elems ws a -> f (Elems ws a)) -> f (Elems ws a)
forall a b. a -> (a -> b) -> b
& (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 ((Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
 -> Elems ws a -> f (Elems ws a))
-> ((a -> f a)
    -> Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
-> (a -> f a)
-> Elems ws a
-> 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
. Index (Vector (Elem Identity ws a))
-> Traversal'
     (Vector (Elem Identity ws a))
     (IxValue (Vector (Elem Identity ws a)))
forall m. Ixed m => Index m -> Traversal' m (IxValue m)
ix Index (Vector (Elem Identity ws a))
Index (CommaSeparated ws a)
i ((Elem Identity ws a -> f (Elem Identity ws a))
 -> Vector (Elem Identity ws a) -> f (Vector (Elem Identity ws a)))
-> ((a -> f a) -> Elem Identity ws a -> f (Elem Identity ws a))
-> (a -> f a)
-> Vector (Elem Identity ws a)
-> f (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
. (a -> f a) -> Elem Identity ws a -> f (Elem Identity ws a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((a -> f a) -> Elems ws a -> f (Elems ws a))
-> (a -> f a) -> Elems ws a -> f (Elems ws a)
forall k (f :: k -> *) s (t :: k) a (b :: k).
LensLike f s t a b -> LensLike f s t a b
%%~ a -> f a
IxValue (CommaSeparated ws a) -> f (IxValue (CommaSeparated ws a))
f

-- | Convert a list of @a@ to a 'Waargonaut.Types.CommaSep.CommaSeparated' list, with no whitespace.
fromList :: (Monoid ws, Semigroup ws) => [a] -> CommaSeparated ws a
fromList :: [a] -> CommaSeparated ws a
fromList = (a -> CommaSeparated ws a -> CommaSeparated ws a)
-> CommaSeparated ws a -> [a] -> CommaSeparated ws a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> CommaSeparated ws a -> CommaSeparated ws a
forall s a. Cons s s a a => a -> s -> s
cons CommaSeparated ws a
forall a. Monoid a => a
mempty
{-# INLINE fromList #-}

-- | Convert a 'Waargonaut.Types.CommaSep.CommaSeparated' of @a@ to @[a]@, discarding whitespace.
toList :: CommaSeparated ws a -> [a]
toList :: CommaSeparated ws a -> [a]
toList = [a] -> (Elems ws a -> [a]) -> Maybe (Elems ws a) -> [a]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Elems ws a -> [a]
forall s ws a. HasElems s ws a => s -> [a]
g (Maybe (Elems ws a) -> [a])
-> (CommaSeparated ws a -> Maybe (Elems ws a))
-> CommaSeparated 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
. (CommaSeparated ws a
-> Getting
     (Maybe (Elems ws a)) (CommaSeparated ws a) (Maybe (Elems ws a))
-> Maybe (Elems ws a)
forall s a. s -> Getting a s a -> a
^. ((ws, Maybe (Elems ws a))
 -> Const (Maybe (Elems ws a)) (ws, Maybe (Elems ws a)))
-> CommaSeparated ws a
-> Const (Maybe (Elems ws a)) (CommaSeparated ws a)
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
_CommaSeparated (((ws, Maybe (Elems ws a))
  -> Const (Maybe (Elems ws a)) (ws, Maybe (Elems ws a)))
 -> CommaSeparated ws a
 -> Const (Maybe (Elems ws a)) (CommaSeparated ws a))
-> ((Maybe (Elems ws a)
     -> Const (Maybe (Elems ws a)) (Maybe (Elems ws a)))
    -> (ws, Maybe (Elems ws a))
    -> Const (Maybe (Elems ws a)) (ws, Maybe (Elems ws a)))
-> Getting
     (Maybe (Elems ws a)) (CommaSeparated ws a) (Maybe (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
. (Maybe (Elems ws a)
 -> Const (Maybe (Elems ws a)) (Maybe (Elems ws a)))
-> (ws, Maybe (Elems ws a))
-> Const (Maybe (Elems ws a)) (ws, Maybe (Elems ws a))
forall s t a b. Field2 s t a b => Lens s t a b
_2) where
  g :: s -> [a]
g s
e = [a] -> a -> [a]
forall s a. Snoc s s a a => s -> a -> s
snoc (s
e s -> Getting (Endo [a]) s a -> [a]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Vector (Elem Identity ws a)
 -> Const (Endo [a]) (Vector (Elem Identity ws a)))
-> s -> Const (Endo [a]) s
forall c ws a.
HasElems c ws a =>
Lens' c (Vector (Elem Identity ws a))
elemsElems ((Vector (Elem Identity ws a)
  -> Const (Endo [a]) (Vector (Elem Identity ws a)))
 -> s -> Const (Endo [a]) s)
-> ((a -> Const (Endo [a]) a)
    -> Vector (Elem Identity ws a)
    -> Const (Endo [a]) (Vector (Elem Identity ws a)))
-> Getting (Endo [a]) s 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 -> Const (Endo [a]) (Elem Identity ws a))
-> Vector (Elem Identity ws a)
-> Const (Endo [a]) (Vector (Elem Identity ws a))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ((Elem Identity ws a -> Const (Endo [a]) (Elem Identity ws a))
 -> Vector (Elem Identity ws a)
 -> Const (Endo [a]) (Vector (Elem Identity ws a)))
-> ((a -> Const (Endo [a]) a)
    -> Elem Identity ws a -> Const (Endo [a]) (Elem Identity ws a))
-> (a -> Const (Endo [a]) a)
-> Vector (Elem Identity ws a)
-> Const (Endo [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
. (a -> Const (Endo [a]) a)
-> Elem Identity ws a -> Const (Endo [a]) (Elem Identity ws a)
forall c (f :: * -> *) ws a. HasElem c f ws a => Lens' c a
elemVal) (s
e s -> Getting a s a -> a
forall s a. s -> Getting a s a -> a
^. (Elem Maybe ws a -> Const a (Elem Maybe ws a)) -> s -> Const a s
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)) -> s -> Const a s)
-> ((a -> Const a a)
    -> Elem Maybe ws a -> Const a (Elem Maybe ws a))
-> Getting a s 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)
{-# INLINE toList #-}

-- | Attempt convert a 'CommaSeparated' to some other value using the given functions.
fromCommaSep
  :: Traversal' j (CommaSeparated ws x)
  -> v
  -> (Elems ws a -> v)
  -> (x -> Maybe a)
  -> j
  -> Either j v
fromCommaSep :: Traversal' j (CommaSeparated ws x)
-> v -> (Elems ws a -> v) -> (x -> Maybe a) -> j -> Either j v
fromCommaSep Traversal' j (CommaSeparated ws x)
_HasCS v
empty Elems ws a -> v
builder x -> Maybe a
decoder j
j =
  case Getting (First (Maybe (Elems ws x))) j (Maybe (Elems ws x))
-> j -> Maybe (Maybe (Elems ws x))
forall s (m :: * -> *) a.
MonadReader s m =>
Getting (First a) s a -> m (Maybe a)
preview ((CommaSeparated ws x
 -> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x))
-> j -> Const (First (Maybe (Elems ws x))) j
Traversal' j (CommaSeparated ws x)
_HasCS ((CommaSeparated ws x
  -> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x))
 -> j -> Const (First (Maybe (Elems ws x))) j)
-> ((Maybe (Elems ws x)
     -> Const (First (Maybe (Elems ws x))) (Maybe (Elems ws x)))
    -> CommaSeparated ws x
    -> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x))
-> Getting (First (Maybe (Elems ws x))) j (Maybe (Elems ws x))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((ws, Maybe (Elems ws x))
 -> Const (First (Maybe (Elems ws x))) (ws, Maybe (Elems ws x)))
-> CommaSeparated ws x
-> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x)
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
_CommaSeparated (((ws, Maybe (Elems ws x))
  -> Const (First (Maybe (Elems ws x))) (ws, Maybe (Elems ws x)))
 -> CommaSeparated ws x
 -> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x))
-> ((Maybe (Elems ws x)
     -> Const (First (Maybe (Elems ws x))) (Maybe (Elems ws x)))
    -> (ws, Maybe (Elems ws x))
    -> Const (First (Maybe (Elems ws x))) (ws, Maybe (Elems ws x)))
-> (Maybe (Elems ws x)
    -> Const (First (Maybe (Elems ws x))) (Maybe (Elems ws x)))
-> CommaSeparated ws x
-> Const (First (Maybe (Elems ws x))) (CommaSeparated ws x)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Maybe (Elems ws x)
 -> Const (First (Maybe (Elems ws x))) (Maybe (Elems ws x)))
-> (ws, Maybe (Elems ws x))
-> Const (First (Maybe (Elems ws x))) (ws, Maybe (Elems ws x))
forall s t a b. Field2 s t a b => Lens s t a b
_2) j
j of
    Maybe (Maybe (Elems ws x))
Nothing         -> j -> Either j v
forall a b. a -> Either a b
Left j
j   -- Json input is not the write structure
    Just Maybe (Elems ws x)
Nothing    -> v -> Either j v
forall a b. b -> Either a b
Right v
empty -- Json input is the right structure but empty so return empty
    Just (Just Elems ws x
els) -> Either j v
-> (Elems ws a -> Either j v) -> Maybe (Elems ws a) -> Either j v
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (j -> Either j v
forall a b. a -> Either a b
Left j
j)                 -- We've had a conversion failure
      (v -> Either j v
forall a b. b -> Either a b
Right (v -> Either j v) -> (Elems ws a -> v) -> Elems ws a -> Either j v
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Elems ws a -> v
builder)        -- Try to lazily fold our values into the return type
      (Maybe (Elems ws a) -> Either j v)
-> Maybe (Elems ws a) -> Either j v
forall a b. (a -> b) -> a -> b
$ (x -> Maybe a) -> Elems ws x -> Maybe (Elems ws a)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse x -> Maybe a
decoder Elems ws x
els   -- Try to decode the values
{-# INLINE fromCommaSep #-}

-- | Parse a 'Waargonaut.Types.CommaSep.CommaSeparated' data structure.
--
-- >>> testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[]"
-- Right (CommaSeparated (WS []) Nothing)
--
-- >>> testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[ ]"
-- Right (CommaSeparated (WS [Space]) Nothing)
--
-- >>> isLeft $ testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[ , ]"
-- True
--
-- >>> isLeft $ testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[ , a]"
-- True
--
-- >>> isLeft $ testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[d a]"
-- True
--
-- >>> testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[d , ]"
-- Right (CommaSeparated (WS []) (Just (Elems {_elemsElems = [], _elemsLast = Elem {_elemVal = ('d',WS [Space]), _elemTrailing = Just (Comma,WS [Space])}})))
--
-- >>> testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[\na\n , b]"
-- Right (CommaSeparated (WS [NewLine]) (Just (Elems {_elemsElems = [Elem {_elemVal = ('a',WS [NewLine,Space]), _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = ('b',WS []), _elemTrailing = Nothing}})))
--
-- >>> testparse (parseCommaSeparated (char '[') (char ']') parseWhitespace charWS) "[\na\n , b, \n]"
-- Right (CommaSeparated (WS [NewLine]) (Just (Elems {_elemsElems = [Elem {_elemVal = ('a',WS [NewLine,Space]), _elemTrailing = Identity (Comma,WS [Space])}], _elemsLast = Elem {_elemVal = ('b',WS []), _elemTrailing = Just (Comma,WS [Space,NewLine])}})))
--
parseCommaSeparated
  :: ( Monad f
     , CharParsing f
     )
  => f open
  -> f close
  -> f ws
  -> f a
  -> f (CommaSeparated ws a)
parseCommaSeparated :: f open -> f close -> f ws -> f a -> f (CommaSeparated ws a)
parseCommaSeparated f open
op f close
fin f ws
ws f a
a =
  f open
op f open -> f (CommaSeparated ws a) -> f (CommaSeparated ws a)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (
    ws -> Maybe (Elems ws a) -> CommaSeparated ws a
forall ws a. ws -> Maybe (Elems ws a) -> CommaSeparated ws a
CommaSeparated (ws -> Maybe (Elems ws a) -> CommaSeparated ws a)
-> f ws -> f (Maybe (Elems ws a) -> CommaSeparated ws a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f ws
ws f (Maybe (Elems ws a) -> CommaSeparated ws a)
-> f (Maybe (Elems ws a)) -> f (CommaSeparated ws a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [f (Maybe (Elems ws a))] -> f (Maybe (Elems ws a))
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum
      [ Maybe (Elems ws a)
forall a. Maybe a
Nothing Maybe (Elems ws a) -> f close -> f (Maybe (Elems ws a))
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f close
fin
      , Elems ws a -> Maybe (Elems ws a)
forall a. a -> Maybe a
Just (Elems ws a -> Maybe (Elems ws a))
-> f (Elems ws a) -> f (Maybe (Elems ws a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f ws -> f a -> f (Elems ws a)
forall (f :: * -> *) ws a.
(Monad f, CharParsing f) =>
f ws -> f a -> f (Elems ws a)
parseCommaSeparatedElems f ws
ws f a
a f (Maybe (Elems ws a)) -> f close -> f (Maybe (Elems ws a))
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* f close
fin
      ]
  )