-- | a 'Boomerang' library for working with '[Text]'
{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, FlexibleInstances, TemplateHaskell, TypeFamilies, TypeSynonymInstances, TypeOperators #-}
module Text.Boomerang.Texts
    (
    -- * Types
      TextsError
    -- * Combinators
    , (</>), alpha, anyChar, anyText, char, digit, digits, signed, eos, integral, int
    , integer, lit, readshow, satisfy, satisfyStr, space
    , rTextCons, rEmpty, rText, rText1
    -- * Running the 'Boomerang'
    , isComplete, parseTexts, unparseTexts
    )
    where

import Prelude                    hiding ((.), id, (/))
import Control.Category           (Category((.), id))
import Data.Char                  (isAlpha, isDigit, isSpace)
import Data.String                (IsString(..))
import           Data.Text        (Text)
import qualified Data.Text        as Text
import qualified Data.Text.Read   as Text
import Text.Boomerang.Combinators (opt, duck1, manyr, somer)
import Text.Boomerang.Error       (ParserError(..),ErrorMsg(..), (<?>), condenseErrors, mkParserError)
import Text.Boomerang.HStack      ((:-)(..), arg)
import Text.Boomerang.Pos         (InitialPosition(..), MajorMinorPos(..), incMajor, incMinor)
import Text.Boomerang.Prim        (Parser(..), Boomerang(..), parse1, xmaph, xpure, unparse1, val)

type TextsError = ParserError MajorMinorPos

instance InitialPosition TextsError where
    initialPos :: Maybe TextsError -> Pos TextsError
initialPos Maybe TextsError
_ = Integer -> Integer -> MajorMinorPos
MajorMinorPos Integer
0 Integer
0

instance a ~ b => IsString (Boomerang TextsError [Text] a b) where
    fromString :: String -> Boomerang TextsError [Text] a b
fromString = forall r. Text -> Boomerang TextsError [Text] r r
lit forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
Text.pack

-- | a constant string
lit :: Text -> Boomerang TextsError [Text] r r
lit :: forall r. Text -> Boomerang TextsError [Text] r r
lit Text
l = forall e tok a b.
Parser e tok (a -> b)
-> (b -> [(tok -> tok, a)]) -> Boomerang e tok a b
Boomerang Parser TextsError [Text] (r -> r)
pf r -> [([Text] -> [Text], r)]
sf
    where
      pf :: Parser TextsError [Text] (r -> r)
pf = forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
tok Pos TextsError
pos ->
           case [Text]
tok of
             [] -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"input", String -> ErrorMsg
Expect (forall a. Show a => a -> String
show Text
l)]
             (Text
p:[Text]
ps)
                 | Text -> Bool
Text.null Text
p Bool -> Bool -> Bool
&& (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ Text -> Bool
Text.null Text
l) -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"segment", String -> ErrorMsg
Expect (forall a. Show a => a -> String
show Text
l)]
                 | Bool
otherwise ->
                     case Text -> Text -> Maybe Text
Text.stripPrefix Text
l Text
p of
                       (Just Text
p') ->
                           [forall a b. b -> Either a b
Right ((forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id, Text
p'forall a. a -> [a] -> [a]
:[Text]
ps), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMinor (Text -> Int
Text.length Text
l) Pos TextsError
pos)]
                       Maybe Text
Nothing ->
                           forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
UnExpect (forall a. Show a => a -> String
show Text
p), String -> ErrorMsg
Expect (forall a. Show a => a -> String
show Text
l)]
      sf :: r -> [([Text] -> [Text], r)]
sf r
b = [ (\[Text]
strings -> case [Text]
strings of [] -> [Text
l] ; (Text
s:[Text]
ss) -> ((Text
l Text -> Text -> Text
`Text.append` Text
s) forall a. a -> [a] -> [a]
: [Text]
ss), r
b)]

infixr 9 </>
-- | equivalent to @f . eos . g@
(</>) :: Boomerang TextsError [Text] b c -> Boomerang TextsError [Text] a b -> Boomerang TextsError [Text] a c
Boomerang TextsError [Text] b c
f </> :: forall b c a.
Boomerang TextsError [Text] b c
-> Boomerang TextsError [Text] a b
-> Boomerang TextsError [Text] a c
</> Boomerang TextsError [Text] a b
g = Boomerang TextsError [Text] b c
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall r. Boomerang TextsError [Text] r r
eos forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Boomerang TextsError [Text] a b
g

-- | end of string
eos :: Boomerang TextsError [Text] r r
eos :: forall r. Boomerang TextsError [Text] r r
eos = forall e tok a b.
Parser e tok (a -> b)
-> (b -> [(tok -> tok, a)]) -> Boomerang e tok a b
Boomerang
       (forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
path Pos TextsError
pos -> case [Text]
path of
                   []      -> [forall a b. b -> Either a b
Right ((forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id, []), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMajor Integer
1 Pos TextsError
pos)]
--                   [] -> mkParserError pos [EOI "input"]
                   (Text
p:[Text]
ps)
                       | Text -> Bool
Text.null Text
p ->
                          [ forall a b. b -> Either a b
Right ((forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id, [Text]
ps), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMajor Integer
1 Pos TextsError
pos) ]
                       | Bool
otherwise -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
Message forall a b. (a -> b) -> a -> b
$ String
"path-segment not entirely consumed: " forall a. [a] -> [a] -> [a]
++ (Text -> String
Text.unpack Text
p)])
       (\r
a -> [((Text
Text.empty forall a. a -> [a] -> [a]
:), r
a)])

-- | statisfy a 'Char' predicate
satisfy :: (Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy :: forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy Char -> Bool
p = forall e tok a r.
Parser e tok a -> (a -> [tok -> tok]) -> Boomerang e tok r (a :- r)
val
  (forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
tok Pos TextsError
pos ->
       case [Text]
tok of
         []     -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"input"]
         (Text
s:[Text]
ss) ->
             case Text -> Maybe (Char, Text)
Text.uncons Text
s of
               Maybe (Char, Text)
Nothing -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"segment"]
               (Just (Char
c, Text
cs))
                   | Char -> Bool
p Char
c ->
                       [forall a b. b -> Either a b
Right ((Char
c, Text
cs forall a. a -> [a] -> [a]
: [Text]
ss), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMinor Integer
1 Pos TextsError
pos )]
                   | Bool
otherwise ->
                       forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
SysUnExpect forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Char
c]
  )
  (\Char
c -> [ \[Text]
paths -> case [Text]
paths of [] -> [Char -> Text
Text.singleton Char
c] ; (Text
s:[Text]
ss) -> ((Char -> Text -> Text
Text.cons Char
c Text
s)forall a. a -> [a] -> [a]
:[Text]
ss) | Char -> Bool
p Char
c ])


-- | satisfy a 'Text' predicate.
--
-- Note: must match the entire remainder of the 'Text' in this segment
satisfyStr :: (Text -> Bool) -> Boomerang TextsError [Text] r (Text :- r)
satisfyStr :: forall r.
(Text -> Bool) -> Boomerang TextsError [Text] r (Text :- r)
satisfyStr Text -> Bool
p = forall e tok a r.
Parser e tok a -> (a -> [tok -> tok]) -> Boomerang e tok r (a :- r)
val
  (forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
tok Pos TextsError
pos ->
       case [Text]
tok of
         []          -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"input"]
         (Text
s:[Text]
ss)
             | Text -> Bool
Text.null Text
s -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"segment"]
             | Text -> Bool
p Text
s ->
                 do [forall a b. b -> Either a b
Right ((Text
s, Text
Text.emptyforall a. a -> [a] -> [a]
:[Text]
ss), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMajor Integer
1 Pos TextsError
pos )]
             | Bool
otherwise ->
                 do forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
SysUnExpect forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Text
s]
  )
  (\Text
str -> [ \[Text]
strings -> case [Text]
strings of [] -> [Text
str] ; (Text
s:[Text]
ss) -> ((Text
str Text -> Text -> Text
`Text.append` Text
s)forall a. a -> [a] -> [a]
:[Text]
ss) | Text -> Bool
p Text
str ])

-- | ascii digits @\'0\'..\'9\'@
digit :: Boomerang TextsError [Text] r (Char :- r)
digit :: forall r. Boomerang TextsError [Text] r (Char :- r)
digit = forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy Char -> Bool
isDigit forall p tok a b.
Boomerang (ParserError p) tok a b
-> String -> Boomerang (ParserError p) tok a b
<?> String
"a digit 0-9"

-- | matches alphabetic Unicode characters (lower-case, upper-case and title-case letters,
-- plus letters of caseless scripts and modifiers letters).  (Uses 'isAlpha')
alpha :: Boomerang TextsError [Text] r (Char :- r)
alpha :: forall r. Boomerang TextsError [Text] r (Char :- r)
alpha = forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy Char -> Bool
isAlpha forall p tok a b.
Boomerang (ParserError p) tok a b
-> String -> Boomerang (ParserError p) tok a b
<?> String
"an alphabetic Unicode character"

-- | matches white-space characters in the Latin-1 range. (Uses 'isSpace')
space :: Boomerang TextsError [Text] r (Char :- r)
space :: forall r. Boomerang TextsError [Text] r (Char :- r)
space = forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy Char -> Bool
isSpace forall p tok a b.
Boomerang (ParserError p) tok a b
-> String -> Boomerang (ParserError p) tok a b
<?> String
"a white-space character"

-- | any character
anyChar :: Boomerang TextsError [Text] r (Char :- r)
anyChar :: forall r. Boomerang TextsError [Text] r (Char :- r)
anyChar = forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy (forall a b. a -> b -> a
const Bool
True)

-- | matches the specified character
char :: Char -> Boomerang TextsError [Text] r (Char :- r)
char :: forall r. Char -> Boomerang TextsError [Text] r (Char :- r)
char Char
c = forall r.
(Char -> Bool) -> Boomerang TextsError [Text] r (Char :- r)
satisfy (forall a. Eq a => a -> a -> Bool
== Char
c) forall p tok a b.
Boomerang (ParserError p) tok a b
-> String -> Boomerang (ParserError p) tok a b
<?> forall a. Show a => a -> String
show [Char
c]

-- | lift 'Read'/'Show' to a 'Boomerang'
--
-- There are a few restrictions here:
--
--  1. Error messages are a bit fuzzy. `Read` does not tell us where
--  or why a parse failed. So all we can do it use the the position
--  that we were at when we called read and say that it failed.
--
--  2. it is (currently) not safe to use 'readshow' on integral values
--  because the 'Read' instance for 'Int', 'Integer', etc,
readshow :: (Read a, Show a) => Boomerang TextsError [Text] r (a :- r)
readshow :: forall a r.
(Read a, Show a) =>
Boomerang TextsError [Text] r (a :- r)
readshow =
    forall e tok a r.
Parser e tok a -> (a -> [tok -> tok]) -> Boomerang e tok r (a :- r)
val forall a. Read a => Parser TextsError [Text] a
readParser forall {a}. Show a => a -> [[Text] -> [Text]]
s
    where
      s :: a -> [[Text] -> [Text]]
s a
a = [ \[Text]
strings -> case [Text]
strings of [] -> [String -> Text
Text.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show a
a] ; (Text
s:[Text]
ss) -> (((String -> Text
Text.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show a
a) Text -> Text -> Text
`Text.append` Text
s)forall a. a -> [a] -> [a]
:[Text]
ss) ]

readParser :: (Read a) => Parser TextsError [Text] a
readParser :: forall a. Read a => Parser TextsError [Text] a
readParser =
    forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
tok Pos TextsError
pos ->
        case [Text]
tok of
          []                  -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"input"]
          (Text
p:[Text]
_) | Text -> Bool
Text.null Text
p -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"segment"]
          (Text
p:[Text]
ps) ->
            case forall a. Read a => ReadS a
reads (Text -> String
Text.unpack Text
p) of
              [] -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
SysUnExpect (Text -> String
Text.unpack Text
p), String -> ErrorMsg
Message forall a b. (a -> b) -> a -> b
$ String
"decoding using 'read' failed."]
              [(a
a,String
r)] ->
                  [forall a b. b -> Either a b
Right ((a
a, (String -> Text
Text.pack String
r)forall a. a -> [a] -> [a]
:[Text]
ps), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMinor ((Text -> Int
Text.length Text
p) forall a. Num a => a -> a -> a
- (forall (t :: * -> *) a. Foldable t => t a -> Int
length String
r)) Pos TextsError
pos)]

readIntegral :: (Integral a) => Text -> a
readIntegral :: forall a. Integral a => Text -> a
readIntegral Text
s =
    case (forall a. Num a => Reader a -> Reader a
Text.signed forall a. Integral a => Reader a
Text.decimal) Text
s of
      (Left String
e) -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"readIntegral: " forall a. [a] -> [a] -> [a]
++ String
e
      (Right (a
a, Text
r))
          | Text -> Bool
Text.null Text
r -> a
a
          | Bool
otherwise -> forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"readIntegral: ambiguous parse. Left over data: " forall a. [a] -> [a] -> [a]
++ Text -> String
Text.unpack Text
r


-- | the empty string
rEmpty :: Boomerang e [Text] r (Text :- r)
rEmpty :: forall e r. Boomerang e [Text] r (Text :- r)
rEmpty = forall a b e tok. (a -> b) -> (b -> Maybe a) -> Boomerang e tok a b
xpure (Text
Text.empty forall a b. a -> b -> a :- b
:-) forall a b. (a -> b) -> a -> b
$
              \(Text
xs :- r
t) ->
                  if Text -> Bool
Text.null Text
xs
                     then (forall a. a -> Maybe a
Just r
t)
                     else forall a. Maybe a
Nothing

-- | the first character of a 'Text'
rTextCons :: Boomerang e tok (Char :- Text :- r) (Text :- r)
rTextCons :: forall e tok r. Boomerang e tok (Char :- (Text :- r)) (Text :- r)
rTextCons =
    forall a b e tok. (a -> b) -> (b -> Maybe a) -> Boomerang e tok a b
xpure (forall ty r s a. (ty -> r -> s) -> (a -> ty) -> (a :- r) -> s
arg (forall ty r s a. (ty -> r -> s) -> (a -> ty) -> (a :- r) -> s
arg forall a b. a -> b -> a :- b
(:-)) (Char -> Text -> Text
Text.cons)) forall a b. (a -> b) -> a -> b
$
          \(Text
xs :- r
t) ->
              do (Char
a, Text
as) <- Text -> Maybe (Char, Text)
Text.uncons Text
xs
                 forall (m :: * -> *) a. Monad m => a -> m a
return (Char
a forall a b. a -> b -> a :- b
:- Text
as forall a b. a -> b -> a :- b
:- r
t)

-- | construct/parse some 'Text' by repeatedly apply a 'Char' 0 or more times parser
rText :: Boomerang e [Text] r (Char :- r)
      -> Boomerang e [Text] r (Text :- r)
rText :: forall e r.
Boomerang e [Text] r (Char :- r)
-> Boomerang e [Text] r (Text :- r)
rText Boomerang e [Text] r (Char :- r)
r = forall e tok r. Boomerang e tok r r -> Boomerang e tok r r
manyr (forall e tok r. Boomerang e tok (Char :- (Text :- r)) (Text :- r)
rTextCons forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall e tok r1 a r2 h.
Boomerang e tok r1 (a :- r2)
-> Boomerang e tok (h :- r1) (a :- (h :- r2))
duck1 Boomerang e [Text] r (Char :- r)
r) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall e r. Boomerang e [Text] r (Text :- r)
rEmpty

-- | construct/parse some 'Text' by repeatedly apply a 'Char' 1 or more times parser
rText1 :: Boomerang e [Text] r (Char :- r)
      -> Boomerang e [Text] r (Text :- r)
rText1 :: forall e r.
Boomerang e [Text] r (Char :- r)
-> Boomerang e [Text] r (Text :- r)
rText1 Boomerang e [Text] r (Char :- r)
r = forall e tok r. Boomerang e tok r r -> Boomerang e tok r r
somer (forall e tok r. Boomerang e tok (Char :- (Text :- r)) (Text :- r)
rTextCons forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall e tok r1 a r2 h.
Boomerang e tok r1 (a :- r2)
-> Boomerang e tok (h :- r1) (a :- (h :- r2))
duck1 Boomerang e [Text] r (Char :- r)
r) forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall e r. Boomerang e [Text] r (Text :- r)
rEmpty


-- | a sequence of one or more digits
digits :: Boomerang TextsError [Text] r (Text :- r)
digits :: forall r. Boomerang TextsError [Text] r (Text :- r)
digits = forall e r.
Boomerang e [Text] r (Char :- r)
-> Boomerang e [Text] r (Text :- r)
rText1 forall r. Boomerang TextsError [Text] r (Char :- r)
digit

-- | an optional - character
--
-- Typically used with 'digits' to support signed numbers
--
-- > signed digits
signed :: Boomerang TextsError [Text] a (Text :- r)
       -> Boomerang TextsError [Text] a (Text :- r)
signed :: forall a r.
Boomerang TextsError [Text] a (Text :- r)
-> Boomerang TextsError [Text] a (Text :- r)
signed Boomerang TextsError [Text] a (Text :- r)
r = forall e tok r. Boomerang e tok r r -> Boomerang e tok r r
opt (forall e tok r. Boomerang e tok (Char :- (Text :- r)) (Text :- r)
rTextCons forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall r. Char -> Boomerang TextsError [Text] r (Char :- r)
char Char
'-') forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Boomerang TextsError [Text] a (Text :- r)
r

-- | matches an 'Integral' value
--
-- Note that the combinator @(rPair . integral . integral)@ is ill-defined because the parse canwell. not tell where it is supposed to split the sequence of digits to produced two ints.
integral :: (Integral a, Show a) => Boomerang TextsError [Text] r (a :- r)
integral :: forall a r.
(Integral a, Show a) =>
Boomerang TextsError [Text] r (a :- r)
integral = forall a b e tok i o.
(a -> b)
-> (b -> Maybe a)
-> Boomerang e tok i (a :- o)
-> Boomerang e tok i (b :- o)
xmaph forall a. Integral a => Text -> a
readIntegral (forall a. a -> Maybe a
Just forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. String -> Text
Text.pack forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall a. Show a => a -> String
show)  (forall a r.
Boomerang TextsError [Text] a (Text :- r)
-> Boomerang TextsError [Text] a (Text :- r)
signed forall r. Boomerang TextsError [Text] r (Text :- r)
digits)

-- | matches an 'Int'
-- Note that the combinator @(rPair . int . int)@ is ill-defined because the parse canwell. not tell where it is supposed to split the sequence of digits to produced two ints.
int :: Boomerang TextsError [Text] r (Int :- r)
int :: forall r. Boomerang TextsError [Text] r (Int :- r)
int = forall a r.
(Integral a, Show a) =>
Boomerang TextsError [Text] r (a :- r)
integral

-- | matches an 'Integer'
--
-- Note that the combinator @(rPair . integer . integer)@ is ill-defined because the parse can not tell where it is supposed to split the sequence of digits to produced two ints.
integer :: Boomerang TextsError [Text] r (Integer :- r)
integer :: forall r. Boomerang TextsError [Text] r (Integer :- r)
integer = forall a r.
(Integral a, Show a) =>
Boomerang TextsError [Text] r (a :- r)
integral

-- | matches any 'Text'
--
-- the parser returns the remainder of the current Text segment, (but does not consume the 'end of segment'.
--
-- Note that the only combinator that should follow 'anyText' is
-- 'eos' or '</>'. Other combinators will lead to inconsistent
-- inversions.
--
-- For example, if we have:
--
-- > unparseTexts (rPair . anyText . anyText)  ("foo","bar")
--
-- That will unparse to @Just ["foobar"]@. But if we call
--
-- > parseTexts (rPair . anyText . anyText)  ["foobar"]
--
-- We will get @Right ("foobar","")@ instead of the original @Right ("foo","bar")@
anyText :: Boomerang TextsError [Text] r (Text :- r)
anyText :: forall r. Boomerang TextsError [Text] r (Text :- r)
anyText = forall e tok a r.
Parser e tok a -> (a -> [tok -> tok]) -> Boomerang e tok r (a :- r)
val Parser TextsError [Text] Text
ps Text -> [[Text] -> [Text]]
ss
    where
      ps :: Parser TextsError [Text] Text
ps = forall e tok a.
(tok -> Pos e -> [Either e ((a, tok), Pos e)]) -> Parser e tok a
Parser forall a b. (a -> b) -> a -> b
$ \[Text]
tok Pos TextsError
pos ->
           case [Text]
tok of
             []     -> forall pos a. pos -> [ErrorMsg] -> [Either (ParserError pos) a]
mkParserError Pos TextsError
pos [String -> ErrorMsg
EOI String
"input", String -> ErrorMsg
Expect String
"any string"]
--             ("":_) -> mkParserError pos [EOI "segment", Expect "any string"]
             (Text
s:[Text]
ss) -> [forall a b. b -> Either a b
Right ((Text
s, Text
Text.emptyforall a. a -> [a] -> [a]
:[Text]
ss), forall i. Integral i => i -> MajorMinorPos -> MajorMinorPos
incMinor (Text -> Int
Text.length Text
s) Pos TextsError
pos)]
      ss :: Text -> [[Text] -> [Text]]
ss Text
str = [\[Text]
ss -> case [Text]
ss of
                         []      -> [Text
str]
                         (Text
s:[Text]
ss') -> ((Text
str Text -> Text -> Text
`Text.append` Text
s) forall a. a -> [a] -> [a]
: [Text]
ss')
               ]

-- | Predicate to test if we have parsed all the Texts.
-- Typically used as argument to 'parse1'
--
-- see also: 'parseTexts'
isComplete :: [Text] -> Bool
isComplete :: [Text] -> Bool
isComplete []   = Bool
True
isComplete [Text
t]  = Text -> Bool
Text.null Text
t
isComplete [Text]
_    = Bool
False

-- | run the parser
--
-- Returns the first complete parse or a parse error.
--
-- > parseTexts (rUnit . lit "foo") ["foo"]
parseTexts :: Boomerang TextsError [Text] () (r :- ())
             -> [Text]
             -> Either TextsError r
parseTexts :: forall r.
Boomerang TextsError [Text] () (r :- ())
-> [Text] -> Either TextsError r
parseTexts Boomerang TextsError [Text] () (r :- ())
pp [Text]
strs =
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall a b. a -> Either a b
Left forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall pos. Ord pos => [ParserError pos] -> ParserError pos
condenseErrors) forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ forall e tok a.
(ErrorPosition e, InitialPosition e, Show e, Ord (Pos e)) =>
(tok -> Bool)
-> Boomerang e tok () (a :- ()) -> tok -> Either [e] a
parse1 [Text] -> Bool
isComplete Boomerang TextsError [Text] () (r :- ())
pp [Text]
strs

-- | run the printer
--
-- > unparseTexts (rUnit . lit "foo") ()
unparseTexts :: Boomerang e [Text] () (r :- ()) -> r -> Maybe [Text]
unparseTexts :: forall e r. Boomerang e [Text] () (r :- ()) -> r -> Maybe [Text]
unparseTexts Boomerang e [Text] () (r :- ())
pp r
r = forall tok e a.
tok -> Boomerang e tok () (a :- ()) -> a -> Maybe tok
unparse1 [] Boomerang e [Text] () (r :- ())
pp r
r