{-# LANGUAGE PatternGuards #-}

module System.Console.CmdArgs.Implicit.Reader(Reader(..), reader) where

import Data.Generics.Any
import qualified Data.Generics.Any.Prelude as A
import System.Console.CmdArgs.Explicit
import Data.Char
import Data.Int
import Data.Word
import Data.List
import Data.Maybe


data Reader = Reader
    {Reader -> String
readerHelp :: String
    ,Reader -> Bool
readerBool :: Bool
    ,Reader -> Int
readerParts :: Int
    ,Reader -> Any -> Any
readerFixup :: Any -> Any -- If a list, then 'reverse', otherwise nothing, so we can build up using cons in O(n)
    ,Reader -> Any -> String -> Either String Any
readerRead :: Any -> String -> Either String Any
    }

-- reader has an actual value of type Any that can be inspected
-- reader_ has a value of type _|_ instead
readerRead_ :: Reader -> String -> Either String Any
readerRead_ Reader
r = Reader -> Any -> String -> Either String Any
readerRead Reader
r (Any -> String -> Either String Any)
-> Any -> String -> Either String Any
forall a b. (a -> b) -> a -> b
$ String -> Any
forall a. HasCallStack => String -> a
error String
"Invariant broken: reader/reader_"


reader :: Any -> Maybe Reader
reader :: Any -> Maybe Reader
reader Any
x | Any -> Bool
A.isList Any
x Bool -> Bool -> Bool
&& Bool -> Bool
not (Any -> Bool
A.isString Any
x) = do
    Reader
r <- Any -> Maybe Reader
reader_ (Any -> Maybe Reader) -> Any -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ Any -> Any
A.fromList Any
x
    Reader -> Maybe Reader
forall (m :: * -> *) a. Monad m => a -> m a
return Reader
r{readerRead :: Any -> String -> Either String Any
readerRead = \Any
o String
s -> (Any -> Any) -> Either String Any -> Either String Any
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Any -> Any -> Any
forall a. Any -> Any -> Any
`A.cons` Any
o) (Either String Any -> Either String Any)
-> Either String Any -> Either String Any
forall a b. (a -> b) -> a -> b
$ Reader -> String -> Either String Any
readerRead_ Reader
r String
s, readerFixup :: Any -> Any
readerFixup = Any -> Any
forall a. Any -> Any
A.reverse}
reader Any
x | Any -> Bool
isAlgType Any
x, [String
ctor] <- Any -> [String]
ctors Any
x, [Any
child] <- Any -> [Any]
children Any
x = do
    -- newtype wrapper, just forward it
    Reader
r <- Any -> Maybe Reader
reader Any
child
    let down :: Any -> Any
down = [Any] -> Any
forall a. [a] -> a
head ([Any] -> Any) -> (Any -> [Any]) -> Any -> Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Any -> [Any]
children
    let up :: Any -> Any -> Any
up Any
o Any
c = Any -> [Any] -> Any
recompose Any
o [Any
c]
    Reader -> Maybe Reader
forall (m :: * -> *) a. Monad m => a -> m a
return Reader
r{readerFixup :: Any -> Any
readerFixup = \Any
x -> Any -> Any -> Any
up Any
x (Any -> Any) -> Any -> Any
forall a b. (a -> b) -> a -> b
$ Reader -> Any -> Any
readerFixup Reader
r (Any -> Any) -> Any -> Any
forall a b. (a -> b) -> a -> b
$ Any -> Any
down Any
x
            ,readerRead :: Any -> String -> Either String Any
readerRead = \Any
x -> (String -> Either String Any)
-> (Any -> Either String Any)
-> Either String Any
-> Either String Any
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Either String Any
forall a b. a -> Either a b
Left (Any -> Either String Any
forall a b. b -> Either a b
Right (Any -> Either String Any)
-> (Any -> Any) -> Any -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Any -> Any -> Any
up Any
x) (Either String Any -> Either String Any)
-> (String -> Either String Any) -> String -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader -> Any -> String -> Either String Any
readerRead Reader
r (Any -> Any
down Any
x)
            }
reader Any
x = Any -> Maybe Reader
reader_ Any
x


reader_ :: Any -> Maybe Reader
reader_ :: Any -> Maybe Reader
reader_ Any
x | Any -> Bool
A.isString Any
x = Reader -> Maybe Reader
forall a. a -> Maybe a
Just (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> Int
-> (Any -> Any)
-> (Any -> String -> Either String Any)
-> Reader
Reader String
"ITEM" Bool
False Int
1 Any -> Any
forall a. a -> a
id ((Any -> String -> Either String Any) -> Reader)
-> (Any -> String -> Either String Any) -> Reader
forall a b. (a -> b) -> a -> b
$ (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ Any -> Either String Any
forall a b. b -> Either a b
Right (Any -> Either String Any)
-> (String -> Any) -> String -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Any
forall a. Data a => a -> Any
Any


reader_ Any
x | Any -> String
typeName Any
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"Bool" = Reader -> Maybe Reader
forall a. a -> Maybe a
Just (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> Int
-> (Any -> Any)
-> (Any -> String -> Either String Any)
-> Reader
Reader String
"BOOL" Bool
True Int
1 Any -> Any
forall a. a -> a
id ((Any -> String -> Either String Any) -> Reader)
-> (Any -> String -> Either String Any) -> Reader
forall a b. (a -> b) -> a -> b
$ (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ \String
s ->
    Either String Any
-> (Bool -> Either String Any) -> Maybe Bool -> Either String Any
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Either String Any
forall a b. a -> Either a b
Left (String -> Either String Any) -> String -> Either String Any
forall a b. (a -> b) -> a -> b
$ String
"Could not read as boolean, " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s) (Any -> Either String Any
forall a b. b -> Either a b
Right (Any -> Either String Any)
-> (Bool -> Any) -> Bool -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Any
forall a. Data a => a -> Any
Any) (Maybe Bool -> Either String Any)
-> Maybe Bool -> Either String Any
forall a b. (a -> b) -> a -> b
$ String -> Maybe Bool
parseBool String
s


reader_ Any
x | Reader
res:[Reader]
_ <- [Maybe Reader] -> [Reader]
forall a. [Maybe a] -> [a]
catMaybes
    [String -> Integer -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Integer
0::Integer), String -> Float -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NUM" (Float
0::Float), String -> Double -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NUM" (Double
0::Double)
    ,String -> Int -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Int
0::Int), String -> Int8 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Int8
0::Int8), String -> Int16 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Int16
0::Int16), String -> Int32 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Int32
0::Int32), String -> Int64 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"INT" (Int64
0::Int64)
    ,String -> Word -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NAT" (Word
0::Word), String -> Word8 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NAT" (Word8
0::Word8), String -> Word16 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NAT" (Word16
0::Word16), String -> Word32 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NAT" (Word32
0::Word32), String -> Word64 -> Maybe Reader
forall a. (Data a, Read a) => String -> a -> Maybe Reader
f String
"NAT" (Word64
0::Word64)
    ] = Reader -> Maybe Reader
forall a. a -> Maybe a
Just Reader
res
    where
        ty :: TypeRep
ty = Any -> TypeRep
typeOf Any
x
        f :: String -> a -> Maybe Reader
f String
hlp a
t | Any -> TypeRep
typeOf (a -> Any
forall a. Data a => a -> Any
Any a
t) TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
/= TypeRep
ty = Maybe Reader
forall a. Maybe a
Nothing
                | Bool
otherwise = Reader -> Maybe Reader
forall a. a -> Maybe a
Just (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> Int
-> (Any -> Any)
-> (Any -> String -> Either String Any)
-> Reader
Reader String
hlp Bool
False Int
1 Any -> Any
forall a. a -> a
id ((Any -> String -> Either String Any) -> Reader)
-> (Any -> String -> Either String Any) -> Reader
forall a b. (a -> b) -> a -> b
$ (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ \String
s -> case ReadS a
forall a. Read a => ReadS a
reads String
s of
            [(a
x,String
"")] -> Any -> Either String Any
forall a b. b -> Either a b
Right (Any -> Either String Any) -> Any -> Either String Any
forall a b. (a -> b) -> a -> b
$ a -> Any
forall a. Data a => a -> Any
Any (a -> Any) -> a -> Any
forall a b. (a -> b) -> a -> b
$ a
x a -> a -> a
forall a. a -> a -> a
`asTypeOf` a
t
            [(a, String)]
_ -> String -> Either String Any
forall a b. a -> Either a b
Left (String -> Either String Any) -> String -> Either String Any
forall a b. (a -> b) -> a -> b
$ String
"Could not read as type " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show (Any -> TypeRep
typeOf (Any -> TypeRep) -> Any -> TypeRep
forall a b. (a -> b) -> a -> b
$ a -> Any
forall a. Data a => a -> Any
Any a
t) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s


reader_ Any
x | Any -> Bool
A.isList Any
x = do
    Reader
r <- Any -> Maybe Reader
reader_ (Any -> Maybe Reader) -> Any -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ Any -> Any
A.fromList Any
x
    Reader -> Maybe Reader
forall (m :: * -> *) a. Monad m => a -> m a
return (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ Reader
r{readerRead :: Any -> String -> Either String Any
readerRead = (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ (Any -> Any) -> Either String Any -> Either String Any
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Any -> Any -> Any
forall a. Any -> Any -> Any
A.list_ Any
x) (Either String Any -> Either String Any)
-> (String -> Either String Any) -> String -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader -> String -> Either String Any
readerRead_ Reader
r}


reader_ Any
x | Any -> Bool
A.isMaybe Any
x = do
    Reader
r <- Any -> Maybe Reader
reader_ (Any -> Maybe Reader) -> Any -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ Any -> Any
A.fromMaybe Any
x
    Reader -> Maybe Reader
forall (m :: * -> *) a. Monad m => a -> m a
return (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ Reader
r{readerRead :: Any -> String -> Either String Any
readerRead = (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ (Any -> Any) -> Either String Any -> Either String Any
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Any -> Any -> Any
forall a. Any -> Any -> Any
A.just_ Any
x) (Either String Any -> Either String Any)
-> (String -> Either String Any) -> String -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader -> String -> Either String Any
readerRead_ Reader
r}


reader_ Any
x | Any -> Bool
isAlgType Any
x Bool -> Bool -> Bool
&& [(String, Any)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, Any)]
xs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Bool -> Bool -> Bool
&& ((String, Any) -> Bool) -> [(String, Any)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) Int
0 (Int -> Bool) -> ((String, Any) -> Int) -> (String, Any) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Any -> Int
arity (Any -> Int) -> ((String, Any) -> Any) -> (String, Any) -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, Any) -> Any
forall a b. (a, b) -> b
snd) [(String, Any)]
xs
    = Reader -> Maybe Reader
forall a. a -> Maybe a
Just (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> Int
-> (Any -> Any)
-> (Any -> String -> Either String Any)
-> Reader
Reader ((Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toUpper (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Any -> String
typeShell Any
x) (Any -> String
typeName Any
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"Bool") Int
1 Any -> Any
forall a. a -> a
id ((Any -> String -> Either String Any) -> Reader)
-> (Any -> String -> Either String Any) -> Reader
forall a b. (a -> b) -> a -> b
$ (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ String -> Either String Any
rd (String -> Either String Any)
-> (String -> String) -> String -> Either String Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower
    where
        xs :: [(String, Any)]
xs = [((Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
c, Any -> String -> Any
compose0 Any
x String
c) | String
c <- Any -> [String]
ctors Any
x]

        rd :: String -> Either String Any
rd String
s | [(String, Any)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(String, Any)]
ys = String -> Either String Any
forall a b. a -> Either a b
Left (String -> Either String Any) -> String -> Either String Any
forall a b. (a -> b) -> a -> b
$ String
"Could not read " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", expected one of: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
unwords (((String, Any) -> String) -> [(String, Any)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Any) -> String
forall a b. (a, b) -> a
fst [(String, Any)]
xs)
             | Just (String
_,Any
x) <- ((String, Any) -> Bool) -> [(String, Any)] -> Maybe (String, Any)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) String
s (String -> Bool)
-> ((String, Any) -> String) -> (String, Any) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, Any) -> String
forall a b. (a, b) -> a
fst) [(String, Any)]
ys = Any -> Either String Any
forall a b. b -> Either a b
Right Any
x
             | [(String, Any)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, Any)]
ys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = String -> Either String Any
forall a b. a -> Either a b
Left (String -> Either String Any) -> String -> Either String Any
forall a b. (a -> b) -> a -> b
$ String
"Ambiguous read for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", could be any of: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [String] -> String
unwords (((String, Any) -> String) -> [(String, Any)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Any) -> String
forall a b. (a, b) -> a
fst [(String, Any)]
ys)
             | Bool
otherwise = Any -> Either String Any
forall a b. b -> Either a b
Right (Any -> Either String Any) -> Any -> Either String Any
forall a b. (a -> b) -> a -> b
$ (String, Any) -> Any
forall a b. (a, b) -> b
snd ((String, Any) -> Any) -> (String, Any) -> Any
forall a b. (a -> b) -> a -> b
$ [(String, Any)] -> (String, Any)
forall a. [a] -> a
head [(String, Any)]
ys
            where ys :: [(String, Any)]
ys = ((String, Any) -> Bool) -> [(String, Any)] -> [(String, Any)]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
isPrefixOf String
s (String -> Bool)
-> ((String, Any) -> String) -> (String, Any) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String, Any) -> String
forall a b. (a, b) -> a
fst) [(String, Any)]
xs


reader_ Any
x | Any -> Bool
isAlgType Any
x, [String
c] <- Any -> [String]
ctors Any
x, Any
x <- Any -> String -> Any
compose0 Any
x String
c = do
    let cs :: [Any]
cs = Any -> [Any]
children Any
x
    [Reader]
rs <- (Any -> Maybe Reader) -> [Any] -> Maybe [Reader]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Any -> Maybe Reader
reader_ [Any]
cs
    let n :: Int
n = [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (Reader -> Int) -> [Reader] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Reader -> Int
readerParts [Reader]
rs
    Reader -> Maybe Reader
forall (m :: * -> *) a. Monad m => a -> m a
return (Reader -> Maybe Reader) -> Reader -> Maybe Reader
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> Int
-> (Any -> Any)
-> (Any -> String -> Either String Any)
-> Reader
Reader ([String] -> String
uncommas ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (Reader -> String) -> [Reader] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Reader -> String
readerHelp [Reader]
rs) ((Reader -> Bool) -> [Reader] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map Reader -> Bool
readerBool [Reader]
rs [Bool] -> [Bool] -> Bool
forall a. Eq a => a -> a -> Bool
== [Bool
True]) Int
n Any -> Any
forall a. a -> a
id ((Any -> String -> Either String Any) -> Reader)
-> (Any -> String -> Either String Any) -> Reader
forall a b. (a -> b) -> a -> b
$ (String -> Either String Any) -> Any -> String -> Either String Any
forall a b. a -> b -> a
const ((String -> Either String Any)
 -> Any -> String -> Either String Any)
-> (String -> Either String Any)
-> Any
-> String
-> Either String Any
forall a b. (a -> b) -> a -> b
$ \String
s ->
        let ss :: [String]
ss = String -> [String]
commas String
s in
        if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 then (Any -> Any) -> Either String Any -> Either String Any
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Any -> [Any] -> Any
recompose Any
x ([Any] -> Any) -> (Any -> [Any]) -> Any -> Any
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Any -> [Any]
forall (m :: * -> *) a. Monad m => a -> m a
return) (Either String Any -> Either String Any)
-> Either String Any -> Either String Any
forall a b. (a -> b) -> a -> b
$ Reader -> String -> Either String Any
readerRead_ ([Reader] -> Reader
forall a. [a] -> a
head ([Reader] -> Reader) -> [Reader] -> Reader
forall a b. (a -> b) -> a -> b
$ (Reader -> Bool) -> [Reader] -> [Reader]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
(==) Int
1 (Int -> Bool) -> (Reader -> Int) -> Reader -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reader -> Int
readerParts) [Reader]
rs) String
s
        else if [String] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
ss Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
n then String -> Either String Any
forall a b. a -> Either a b
Left String
"Incorrect number of commas for fields"
        else ([Any] -> Any) -> Either String [Any] -> Either String Any
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Any -> [Any] -> Any
recompose Any
x) (Either String [Any] -> Either String Any)
-> Either String [Any] -> Either String Any
forall a b. (a -> b) -> a -> b
$ [Either String Any] -> Either String [Any]
forall a a. [Either a a] -> Either a [a]
sequenceEither ([Either String Any] -> Either String [Any])
-> [Either String Any] -> Either String [Any]
forall a b. (a -> b) -> a -> b
$ (Reader -> String -> Either String Any)
-> [Reader] -> [String] -> [Either String Any]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Reader -> String -> Either String Any
readerRead_ [Reader]
rs ([String] -> [Either String Any])
-> [String] -> [Either String Any]
forall a b. (a -> b) -> a -> b
$ ([String] -> String) -> [[String]] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map [String] -> String
uncommas ([[String]] -> [String]) -> [[String]] -> [String]
forall a b. (a -> b) -> a -> b
$ [Int] -> [String] -> [[String]]
forall a. [Int] -> [a] -> [[a]]
takes ((Reader -> Int) -> [Reader] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Reader -> Int
readerParts [Reader]
rs) [String]
ss


reader_ Any
_ = Maybe Reader
forall a. Maybe a
Nothing


uncommas :: [String] -> String
uncommas = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
","
commas :: String -> [String]
commas = String -> [String]
lines (String -> [String]) -> (String -> String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map (\Char
x -> if Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
',' then Char
'\n' else Char
x)


takes :: [Int] -> [a] -> [[a]]
takes [] [a]
_ = []
takes (Int
i:[Int]
is) [a]
xs = [a]
a [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: [Int] -> [a] -> [[a]]
takes [Int]
is [a]
b
    where ([a]
a,[a]
b) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
i [a]
xs

sequenceEither :: [Either a a] -> Either a [a]
sequenceEither = (Either a a -> Either a [a] -> Either a [a])
-> Either a [a] -> [Either a a] -> Either a [a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Either a a -> Either a [a] -> Either a [a]
forall a a. Either a a -> Either a [a] -> Either a [a]
f ([a] -> Either a [a]
forall a b. b -> Either a b
Right [])
    where f :: Either a a -> Either a [a] -> Either a [a]
f (Left a
x) Either a [a]
_ = a -> Either a [a]
forall a b. a -> Either a b
Left a
x
          f Either a a
_ (Left a
x) = a -> Either a [a]
forall a b. a -> Either a b
Left a
x
          f (Right a
x) (Right [a]
xs) = [a] -> Either a [a]
forall a b. b -> Either a b
Right (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs)