lib: refactor sign parser
- Extracts the handling of signs out of `fromRawNumber` and into `signp` itself - Rationale: The sign can be applied independently from the logic in `fromRawNumber`
This commit is contained in:
parent
d28862d10d
commit
cf9b2001e7
@ -101,7 +101,7 @@ import Control.Monad.State.Strict
|
||||
import Data.Bifunctor
|
||||
import Data.Char
|
||||
import Data.Data
|
||||
import Data.Decimal (DecimalRaw (Decimal), Decimal)
|
||||
import Data.Decimal (DecimalRaw (Decimal))
|
||||
import Data.Default
|
||||
import Data.Functor.Identity
|
||||
import Data.List.Compat
|
||||
@ -534,11 +534,8 @@ amountp' s =
|
||||
mamountp' :: String -> MixedAmount
|
||||
mamountp' = Mixed . (:[]) . amountp'
|
||||
|
||||
signp :: TextParser m String
|
||||
signp = do
|
||||
sign <- optional $ oneOf ("+-" :: [Char])
|
||||
return $ case sign of Just '-' -> "-"
|
||||
_ -> ""
|
||||
signp :: Num a => TextParser m (a -> a)
|
||||
signp = char '-' *> pure negate <|> char '+' *> pure id <|> pure id
|
||||
|
||||
multiplierp :: TextParser m Bool
|
||||
multiplierp = option False $ char '*' *> pure True
|
||||
@ -565,8 +562,7 @@ leftsymbolamountp = do
|
||||
(q,prec,mdec,mgrps) <- lift $ numberp suggestedStyle
|
||||
let s = amountstyle{ascommodityside=L, ascommodityspaced=commodityspaced, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}
|
||||
p <- priceamountp
|
||||
let applysign = if sign=="-" then negate else id
|
||||
return $ applysign $ Amount c q p s m
|
||||
return $ Amount c (sign q) p s m
|
||||
<?> "left-symbol amount"
|
||||
|
||||
rightsymbolamountp :: Monad m => JournalParser m Amount
|
||||
@ -578,8 +574,8 @@ rightsymbolamountp = do
|
||||
commodityspaced <- lift $ skipMany' spacenonewline
|
||||
c <- lift commoditysymbolp
|
||||
suggestedStyle <- getAmountStyle c
|
||||
let (q0,prec0,mdec,mgrps) = fromRawNumber suggestedStyle (sign == "-") rawnum
|
||||
(q, prec) = expMod (q0, prec0)
|
||||
let (q0,prec0,mdec,mgrps) = fromRawNumber suggestedStyle rawnum
|
||||
(q, prec) = expMod (sign q0, prec0)
|
||||
p <- priceamountp
|
||||
let s = amountstyle{ascommodityside=R, ascommodityspaced=commodityspaced, asprecision=prec, asdecimalpoint=mdec, asdigitgroups=mgrps}
|
||||
return $ Amount c q p s m
|
||||
@ -677,17 +673,22 @@ numberp suggestedStyle = do
|
||||
sign <- signp
|
||||
raw <- rawnumberp
|
||||
dbg8 "numberp suggestedStyle" suggestedStyle `seq` return ()
|
||||
let num@(q, prec, decSep, groups) = dbg8 "numberp quantity,precision,mdecimalpoint,mgrps" (fromRawNumber suggestedStyle (sign == "-") raw)
|
||||
option num . try $ do
|
||||
when (isJust groups) $ fail "groups and exponent are not mixable"
|
||||
(q', prec') <- exponentp <*> pure (q, prec)
|
||||
return (q', prec', decSep, groups)
|
||||
let (q, prec, decSep, groups) =
|
||||
dbg8 "numberp quantity,precision,mdecimalpoint,mgrps"
|
||||
$ fromRawNumber suggestedStyle raw
|
||||
mExp <- optional $ try $ exponentp
|
||||
case mExp of
|
||||
Just expFunc
|
||||
| isJust groups -> fail "groups and exponent are not mixable"
|
||||
| otherwise -> let (q', prec') = expFunc (q, prec)
|
||||
in pure (sign q', prec', decSep, groups)
|
||||
Nothing -> pure (sign q, prec, decSep, groups)
|
||||
<?> "numberp"
|
||||
|
||||
exponentp :: TextParser m ((Quantity, Int) -> (Quantity, Int))
|
||||
exponentp = do
|
||||
char' 'e'
|
||||
exp <- liftM read $ (++) <$> signp <*> some digitChar
|
||||
exp <- ($) <$> signp <*> (read <$> some digitChar)
|
||||
return $ bimap (* 10^^exp) (max 0 . subtract exp)
|
||||
<?> "exponentp"
|
||||
|
||||
@ -704,25 +705,24 @@ exponentp = do
|
||||
-- - the digit group style, if any (digit group character and sizes of digit groups)
|
||||
fromRawNumber
|
||||
:: Maybe AmountStyle
|
||||
-> Bool
|
||||
-> RawNumber
|
||||
-> (Quantity, Int, Maybe Char, Maybe DigitGroupStyle)
|
||||
fromRawNumber suggestedStyle negated raw = case raw of
|
||||
fromRawNumber suggestedStyle raw = case raw of
|
||||
|
||||
LeadingDecimalPt decPt digitGrp ->
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision) (digitGroupNumber digitGrp)
|
||||
precision = digitGroupLength digitGrp
|
||||
in (quantity, precision, Just decPt, Nothing)
|
||||
|
||||
TrailingDecimalPt digitGrp decPt ->
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision) (digitGroupNumber digitGrp)
|
||||
precision = 0
|
||||
in (quantity, precision, Just decPt, Nothing)
|
||||
|
||||
NoSeparators digitGrp ->
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision) (digitGroupNumber digitGrp)
|
||||
precision = 0
|
||||
in (quantity, precision, Nothing, Nothing)
|
||||
@ -734,7 +734,7 @@ fromRawNumber suggestedStyle negated raw = case raw of
|
||||
&& maybe True (sep `isValidDecimalBy`) suggestedStyle ->
|
||||
|
||||
-- Assuming that the separator is a decimal point
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision)
|
||||
(digitGroupNumber $ digitGrp1 <> digitGrp2)
|
||||
precision = digitGroupLength digitGrp2
|
||||
@ -742,7 +742,7 @@ fromRawNumber suggestedStyle negated raw = case raw of
|
||||
|
||||
| otherwise ->
|
||||
-- Assuming that the separator is digit separator
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision)
|
||||
(digitGroupNumber $ digitGrp1 <> digitGrp2)
|
||||
precision = 0
|
||||
@ -751,7 +751,7 @@ fromRawNumber suggestedStyle negated raw = case raw of
|
||||
in (quantity, precision, Nothing, digitGroupStyle)
|
||||
|
||||
DigitSeparators digitSep digitGrps ->
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision)
|
||||
(digitGroupNumber $ mconcat digitGrps)
|
||||
precision = 0
|
||||
@ -759,7 +759,7 @@ fromRawNumber suggestedStyle negated raw = case raw of
|
||||
in (quantity, precision, Nothing, digitGroupStyle)
|
||||
|
||||
BothSeparators digitSep digitGrps decPt decimalGrp ->
|
||||
let quantity = sign $
|
||||
let quantity =
|
||||
Decimal (fromIntegral precision)
|
||||
(digitGroupNumber $ mconcat digitGrps <> decimalGrp)
|
||||
precision = digitGroupLength decimalGrp
|
||||
@ -767,10 +767,6 @@ fromRawNumber suggestedStyle negated raw = case raw of
|
||||
in (quantity, precision, Just decPt, digitGroupStyle)
|
||||
|
||||
where
|
||||
|
||||
sign :: Decimal -> Decimal
|
||||
sign = if negated then negate else id
|
||||
|
||||
-- Outputs digit group sizes from least significant to most significant
|
||||
groupSizes :: [DigitGrp] -> [Int]
|
||||
groupSizes digitGrps = reverse $ case map digitGroupLength digitGrps of
|
||||
|
||||
Loading…
Reference in New Issue
Block a user