module AmountParser (parseAmount) where

import           Data.Text (Text)
import qualified Hledger as HL
import           Data.Functor.Identity
import           Control.Monad.Trans.State.Strict
import           Text.Megaparsec
import           Text.Megaparsec.Char

type Parser a = HL.JournalParser Identity a

parseAmount :: HL.Journal -> Text -> Either String HL.MixedAmount
parseAmount :: Journal -> Text -> Either String MixedAmount
parseAmount Journal
journal Text
t = case forall a. Identity a -> a
runIdentity forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) e s a.
Monad m =>
ParsecT e s m a
-> String -> s -> m (Either (ParseErrorBundle s e) a)
runParserT (forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (StateT
  Journal (ParsecT HledgerParseErrorData Text Identity) MixedAmount
mixed forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall e s (m :: * -> *). MonadParsec e s m => m ()
eof) Journal
journal) String
"" Text
t of
  Left ParseErrorBundle Text HledgerParseErrorData
err -> forall a b. a -> Either a b
Left (forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseErrorBundle Text HledgerParseErrorData
err)
  Right MixedAmount
res -> forall a b. b -> Either a b
Right MixedAmount
res

mixed :: Parser HL.MixedAmount
mixed :: StateT
  Journal (ParsecT HledgerParseErrorData Text Identity) MixedAmount
mixed = forall (t :: * -> *). Foldable t => t Amount -> MixedAmount
HL.mixed forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [Amount]
expr

expr :: Parser [HL.Amount]
expr :: Parser [Amount]
expr = forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some (forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try forall a b. (a -> b) -> a -> b
$ forall a. Parser a -> Parser a
lexeme StateT Journal (ParsecT HledgerParseErrorData Text Identity) Amount
factor)

factor :: Parser HL.Amount
factor :: StateT Journal (ParsecT HledgerParseErrorData Text Identity) Amount
factor =  (forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
'+' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Parser a -> Parser a
lexeme forall (m :: * -> *). JournalParser m Amount
HL.amountp)
      forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
'-' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Quantity -> Amount -> Amount
HL.divideAmount (-Quantity
1) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Parser a -> Parser a
lexeme forall (m :: * -> *). JournalParser m Amount
HL.amountp)
      forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall (m :: * -> *). JournalParser m Amount
HL.amountp

lexeme :: Parser a -> Parser a
lexeme :: forall a. Parser a -> Parser a
lexeme Parser a
p = forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser a
p