1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE NamedFieldPuns #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE ScopedTypeVariables #-}
5 {-# LANGUAGE TupleSections #-}
6 {-# LANGUAGE TypeFamilies #-}
7 module Hcompta.Account.Read where
9 import qualified Data.Char
10 import Data.String (fromString)
11 import Data.Typeable ()
12 import qualified Text.Parsec as R hiding
25 import Text.Parsec (Stream, ParsecT, (<|>))
27 import qualified Hcompta.Account as Account
28 import Hcompta.Account (Account)
29 import qualified Hcompta.Lib.Regex as Regex
30 import Hcompta.Lib.Regex (Regex)
31 import qualified Hcompta.Lib.Parsec as R
38 -- | Read an 'Account'.
39 account :: Stream s m Char => ParsecT s u m Account
41 R.notFollowedBy $ R.space_horizontal
42 Account.from_List <$> do
43 R.many1_separated section $ R.char section_sep
45 -- | Read an Account.'Account.Name'.
49 section :: Stream s m Char => ParsecT s u m Account.Name
52 R.many1 $ R.try account_name_char
54 account_name_char :: Stream s m Char => ParsecT s u m Char
55 account_name_char = do
58 _ | c == comment_begin -> R.parserZero
59 _ | c == section_sep -> R.parserZero
60 _ | c /= '\t' && R.is_space_horizontal c -> do
61 _ <- R.notFollowedBy $ R.space_horizontal
62 return c <* (R.lookAhead $ R.try $
63 ( R.try (R.char section_sep)
66 _ | not (Data.Char.isSpace c) -> return c
69 -- | Read an Account.'Account.Joker_Name'.
70 joker_section :: Stream s m Char => ParsecT s u m Account.Joker_Name
72 n <- R.option Nothing $ (Just <$> section)
74 Nothing -> R.char section_sep >> (return $ Account.Joker_Any)
75 Just n' -> return $ Account.Joker_Name n'
77 -- | Read an Account.'Account.Joker'.
78 joker :: Stream s m Char => ParsecT s u m Account.Joker
80 R.notFollowedBy $ R.space_horizontal
81 R.many1_separated joker_section $ R.char section_sep
84 regex :: Stream s m Char => ParsecT s u m Regex
86 re <- R.many1 $ R.satisfy (not . R.is_space_horizontal)
89 -- | Read an Account.'Account.Filter'.
90 pattern :: Stream s m Char => ParsecT s u m Account.Pattern
93 [ Account.Pattern_Exact <$> (R.char '=' >> account)
94 , Account.Pattern_Joker <$> (R.char '*' >> joker)
95 , Account.Pattern_Regex <$> (R.option '~' (R.char '~') >> regex)