;csv: refactor amount parsing
This commit is contained in:
		
							parent
							
								
									dae007a372
								
							
						
					
					
						commit
						4242a8592a
					
				| @ -1024,55 +1024,64 @@ getAmount rules record currency p1IsVirtual n = | |||||||
|              "\t=> value: " ++ showMixedAmount a -- XXX not sure this is showing all the right info |              "\t=> value: " ++ showMixedAmount a -- XXX not sure this is showing all the right info | ||||||
|            | (f,a) <- fs] |            | (f,a) <- fs] | ||||||
| 
 | 
 | ||||||
|   where |  | ||||||
|     -- | Given a non-empty amount string to parse, along with a possibly |  | ||||||
|     -- non-empty currency symbol to prepend, parse as a hledger amount (as |  | ||||||
|     -- in journal format), or raise an error. |  | ||||||
|     -- The CSV rules and record are provided for the error message. |  | ||||||
|     parseAmount :: CsvRules -> CsvRecord -> String -> String -> MixedAmount |  | ||||||
|     parseAmount rules record currency amountstr = |  | ||||||
|       either mkerror (Mixed . (:[])) $  -- PARTIAL: |  | ||||||
|       runParser (evalStateT (amountp <* eof) nulljournal) "" $ |  | ||||||
|       T.pack $ (currency++) $ simplifySign amountstr |  | ||||||
|       where |  | ||||||
|         mkerror e = error' $ unlines |  | ||||||
|           ["error: could not parse \""++amountstr++"\" as an amount" |  | ||||||
|           ,showRecord record |  | ||||||
|           ,showRules rules record |  | ||||||
|           -- ,"the default-currency is: "++fromMaybe "unspecified" (getDirective "default-currency" rules) |  | ||||||
|           ,"the parse error is:      "++customErrorBundlePretty e |  | ||||||
|           ,"you may need to " |  | ||||||
|            ++"change your amount*, balance*, or currency* rules, " |  | ||||||
|            ++"or add or change your skip rule" |  | ||||||
|           ] |  | ||||||
| 
 |  | ||||||
| -- | Figure out the expected balance (assertion or assignment) specified for posting N, | -- | Figure out the expected balance (assertion or assignment) specified for posting N, | ||||||
| -- if any (and its parse position). | -- if any (and its parse position). | ||||||
| getBalance :: CsvRules -> CsvRecord -> String -> Int -> Maybe (Amount, GenericSourcePos) | getBalance :: CsvRules -> CsvRecord -> String -> Int -> Maybe (Amount, GenericSourcePos) | ||||||
| getBalance rules record currency n = | getBalance rules record currency n = do | ||||||
|   (fieldval ("balance"++show n) |   v <- (fieldval ("balance"++show n) | ||||||
|     -- for posting 1, also recognise the old field name |         -- for posting 1, also recognise the old field name | ||||||
|     <|> if n==1 then fieldval "balance" else Nothing) |         <|> if n==1 then fieldval "balance" else Nothing) | ||||||
|   >>= parsebalance currency n . strip |   case v of | ||||||
|  |     "" -> Nothing | ||||||
|  |     s  -> Just ( | ||||||
|  |             parseBalanceAmount rules record currency n s | ||||||
|  |            ,nullsourcepos  -- parse position to show when assertion fails, | ||||||
|  |            )               -- XXX the csv record's line number would be good | ||||||
|  |    | ||||||
|   where |   where | ||||||
|     parsebalance currency n s |     fieldval = fmap strip . hledgerFieldValue rules record :: HledgerFieldName -> Maybe String | ||||||
|       | null s    = Nothing | 
 | ||||||
|       | otherwise = Just | -- | Given a non-empty amount string (from CSV) to parse, along with a | ||||||
|           (either (mkerror n s) id $ | -- possibly non-empty currency symbol to prepend, | ||||||
|             runParser (evalStateT (amountp <* eof) nulljournal) "" $ | -- parse as a hledger MixedAmount (as in journal format), or raise an error. | ||||||
|             T.pack $ (currency++) $ simplifySign s | -- The whole CSV record is provided for the error message. | ||||||
|           ,nullsourcepos)  -- XXX parse position to show when assertion fails, | parseAmount :: CsvRules -> CsvRecord -> String -> String -> MixedAmount | ||||||
|                            -- the csv record's line number would be good | parseAmount rules record currency s = | ||||||
|       where |   either mkerror (Mixed . (:[])) $  -- PARTIAL: | ||||||
|         mkerror n s e = error' $ unlines |   runParser (evalStateT (amountp <* eof) nulljournal) "" $ | ||||||
|           ["error: could not parse \""++s++"\" as balance"++show n++" amount" |   T.pack $ (currency++) $ simplifySign s | ||||||
|           ,showRecord record |   where | ||||||
|           ,showRules rules record |     mkerror e = error' $ unlines | ||||||
|           -- ,"the default-currency is: "++fromMaybe "unspecified" mdefaultcurrency |       ["error: could not parse \""++s++"\" as an amount" | ||||||
|           ,"the parse error is:      "++customErrorBundlePretty e |       ,showRecord record | ||||||
|           ] |       ,showRules rules record | ||||||
|     -- mdefaultcurrency = rule "default-currency" |       -- ,"the default-currency is: "++fromMaybe "unspecified" (getDirective "default-currency" rules) | ||||||
|     fieldval = hledgerFieldValue rules record :: HledgerFieldName -> Maybe String |       ,"the parse error is:      "++customErrorBundlePretty e | ||||||
|  |       ,"you may need to " | ||||||
|  |         ++"change your amount*, balance*, or currency* rules, " | ||||||
|  |         ++"or add or change your skip rule" | ||||||
|  |       ] | ||||||
|  | 
 | ||||||
|  | -- XXX unify these | ||||||
|  | -- | Almost but not quite the same as parseAmount. | ||||||
|  | -- Given a non-empty amount string (from CSV) to parse, along with a | ||||||
|  | -- possibly non-empty currency symbol to prepend, | ||||||
|  | -- parse as a hledger Amount (as in journal format), or raise an error. | ||||||
|  | -- The CSV record and the field's numeric suffix are provided for the error message. | ||||||
|  | parseBalanceAmount :: CsvRules -> CsvRecord -> String -> Int -> String -> Amount | ||||||
|  | parseBalanceAmount rules record currency n s = | ||||||
|  |   either (mkerror n s) id $ | ||||||
|  |     runParser (evalStateT (amountp <* eof) nulljournal) "" $ | ||||||
|  |     T.pack $ (currency++) $ simplifySign s | ||||||
|  |                   -- the csv record's line number would be good | ||||||
|  |   where | ||||||
|  |     mkerror n s e = error' $ unlines | ||||||
|  |       ["error: could not parse \""++s++"\" as balance"++show n++" amount" | ||||||
|  |       ,showRecord record | ||||||
|  |       ,showRules rules record | ||||||
|  |       -- ,"the default-currency is: "++fromMaybe "unspecified" mdefaultcurrency | ||||||
|  |       ,"the parse error is:      "++customErrorBundlePretty e | ||||||
|  |       ] | ||||||
| 
 | 
 | ||||||
| -- | Make a balance assertion for the given amount, with the given parse | -- | Make a balance assertion for the given amount, with the given parse | ||||||
| -- position (to be shown in assertion failures), with the assertion type | -- position (to be shown in assertion failures), with the assertion type | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user