{-# LANGUAGE DeriveDataTypeable, OverloadedStrings, ViewPatterns #-}
{-# LANGUAGE CPP #-}
module Hledger.Query (
Query(..),
QueryOpt(..),
parseQuery,
simplifyQuery,
filterQuery,
queryIsNull,
queryIsAcct,
queryIsAmt,
queryIsDepth,
queryIsDate,
queryIsDate2,
queryIsDateOrDate2,
queryIsStartDateOnly,
queryIsSym,
queryIsReal,
queryIsStatus,
queryIsEmpty,
queryStartDate,
queryEndDate,
queryDateSpan,
queryDateSpan',
queryDepth,
inAccount,
inAccountQuery,
matchesTransaction,
matchesPosting,
matchesAccount,
matchesMixedAmount,
matchesAmount,
matchesCommodity,
matchesPriceDirective,
words'',
tests_Query
)
where
import Data.Data
import Data.Either
import Data.List
import Data.Maybe
#if !(MIN_VERSION_base(4,11,0))
import Data.Monoid ((<>))
#endif
import qualified Data.Text as T
import Data.Time.Calendar
import Safe (readDef, headDef)
import Text.Megaparsec
import Text.Megaparsec.Char
import Hledger.Utils hiding (words')
import Hledger.Data.Types
import Hledger.Data.AccountName
import Hledger.Data.Amount (nullamt, usd)
import Hledger.Data.Dates
import Hledger.Data.Posting
import Hledger.Data.Transaction
data Query = Any
| None
| Not Query
| Or [Query]
| And [Query]
| Code Regexp
| Desc Regexp
| Acct Regexp
| Date DateSpan
| Date2 DateSpan
| StatusQ Status
| Real Bool
| Amt OrdPlus Quantity
| Sym Regexp
| Empty Bool
| Depth Int
| Tag Regexp (Maybe Regexp)
deriving (Query -> Query -> Bool
(Query -> Query -> Bool) -> (Query -> Query -> Bool) -> Eq Query
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Query -> Query -> Bool
$c/= :: Query -> Query -> Bool
== :: Query -> Query -> Bool
$c== :: Query -> Query -> Bool
Eq,Typeable Query
Constr
DataType
Typeable Query =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Query -> c Query)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Query)
-> (Query -> Constr)
-> (Query -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Query))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Query))
-> ((forall b. Data b => b -> b) -> Query -> Query)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r)
-> (forall u. (forall d. Data d => d -> u) -> Query -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Query -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Query -> m Query)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Query -> m Query)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Query -> m Query)
-> Data Query
Query -> Constr
Query -> DataType
(forall b. Data b => b -> b) -> Query -> Query
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Query -> c Query
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Query
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Query -> u
forall u. (forall d. Data d => d -> u) -> Query -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Query -> m Query
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Query -> m Query
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Query
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Query -> c Query
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Query)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Query)
$cTag :: Constr
$cDepth :: Constr
$cEmpty :: Constr
$cSym :: Constr
$cAmt :: Constr
$cReal :: Constr
$cStatusQ :: Constr
$cDate2 :: Constr
$cDate :: Constr
$cAcct :: Constr
$cDesc :: Constr
$cCode :: Constr
$cAnd :: Constr
$cOr :: Constr
$cNot :: Constr
$cNone :: Constr
$cAny :: Constr
$tQuery :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Query -> m Query
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Query -> m Query
gmapMp :: (forall d. Data d => d -> m d) -> Query -> m Query
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Query -> m Query
gmapM :: (forall d. Data d => d -> m d) -> Query -> m Query
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Query -> m Query
gmapQi :: Int -> (forall d. Data d => d -> u) -> Query -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Query -> u
gmapQ :: (forall d. Data d => d -> u) -> Query -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Query -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Query -> r
gmapT :: (forall b. Data b => b -> b) -> Query -> Query
$cgmapT :: (forall b. Data b => b -> b) -> Query -> Query
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Query)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Query)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Query)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Query)
dataTypeOf :: Query -> DataType
$cdataTypeOf :: Query -> DataType
toConstr :: Query -> Constr
$ctoConstr :: Query -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Query
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Query
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Query -> c Query
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Query -> c Query
$cp1Data :: Typeable Query
Data,Typeable)
instance Show Query where
show :: Query -> String
show Any = "Any"
show None = "None"
show (Not q :: Query
q) = "Not (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Query -> String
forall a. Show a => a -> String
show Query
q String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
show (Or qs :: [Query]
qs) = "Or (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Query] -> String
forall a. Show a => a -> String
show [Query]
qs String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
show (And qs :: [Query]
qs) = "And (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [Query] -> String
forall a. Show a => a -> String
show [Query]
qs String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
show (Code r :: String
r) = "Code " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
r
show (Desc r :: String
r) = "Desc " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
r
show (Acct r :: String
r) = "Acct " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
r
show (Date ds :: DateSpan
ds) = "Date (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ DateSpan -> String
forall a. Show a => a -> String
show DateSpan
ds String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
show (Date2 ds :: DateSpan
ds) = "Date2 (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ DateSpan -> String
forall a. Show a => a -> String
show DateSpan
ds String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
show (StatusQ b :: Status
b) = "StatusQ " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Status -> String
forall a. Show a => a -> String
show Status
b
show (Real b :: Bool
b) = "Real " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show Bool
b
show (Amt ord :: OrdPlus
ord qty :: Quantity
qty) = "Amt " String -> ShowS
forall a. [a] -> [a] -> [a]
++ OrdPlus -> String
forall a. Show a => a -> String
show OrdPlus
ord String -> ShowS
forall a. [a] -> [a] -> [a]
++ " " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Quantity -> String
forall a. Show a => a -> String
show Quantity
qty
show (Sym r :: String
r) = "Sym " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
r
show (Empty b :: Bool
b) = "Empty " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> String
forall a. Show a => a -> String
show Bool
b
show (Depth n :: Int
n) = "Depth " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n
show (Tag s :: String
s ms :: Maybe String
ms) = "Tag " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> String
show String
s String -> ShowS
forall a. [a] -> [a] -> [a]
++ " (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe String -> String
forall a. Show a => a -> String
show Maybe String
ms String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
data OrdPlus = Lt | LtEq | Gt | GtEq | Eq | AbsLt | AbsLtEq | AbsGt | AbsGtEq | AbsEq
deriving (Int -> OrdPlus -> ShowS
[OrdPlus] -> ShowS
OrdPlus -> String
(Int -> OrdPlus -> ShowS)
-> (OrdPlus -> String) -> ([OrdPlus] -> ShowS) -> Show OrdPlus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OrdPlus] -> ShowS
$cshowList :: [OrdPlus] -> ShowS
show :: OrdPlus -> String
$cshow :: OrdPlus -> String
showsPrec :: Int -> OrdPlus -> ShowS
$cshowsPrec :: Int -> OrdPlus -> ShowS
Show,OrdPlus -> OrdPlus -> Bool
(OrdPlus -> OrdPlus -> Bool)
-> (OrdPlus -> OrdPlus -> Bool) -> Eq OrdPlus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OrdPlus -> OrdPlus -> Bool
$c/= :: OrdPlus -> OrdPlus -> Bool
== :: OrdPlus -> OrdPlus -> Bool
$c== :: OrdPlus -> OrdPlus -> Bool
Eq,Typeable OrdPlus
Constr
DataType
Typeable OrdPlus =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrdPlus -> c OrdPlus)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrdPlus)
-> (OrdPlus -> Constr)
-> (OrdPlus -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OrdPlus))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OrdPlus))
-> ((forall b. Data b => b -> b) -> OrdPlus -> OrdPlus)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r)
-> (forall u. (forall d. Data d => d -> u) -> OrdPlus -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> OrdPlus -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus)
-> Data OrdPlus
OrdPlus -> Constr
OrdPlus -> DataType
(forall b. Data b => b -> b) -> OrdPlus -> OrdPlus
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrdPlus -> c OrdPlus
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrdPlus
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> OrdPlus -> u
forall u. (forall d. Data d => d -> u) -> OrdPlus -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrdPlus
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrdPlus -> c OrdPlus
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OrdPlus)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OrdPlus)
$cAbsEq :: Constr
$cAbsGtEq :: Constr
$cAbsGt :: Constr
$cAbsLtEq :: Constr
$cAbsLt :: Constr
$cEq :: Constr
$cGtEq :: Constr
$cGt :: Constr
$cLtEq :: Constr
$cLt :: Constr
$tOrdPlus :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
gmapMp :: (forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
gmapM :: (forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> OrdPlus -> m OrdPlus
gmapQi :: Int -> (forall d. Data d => d -> u) -> OrdPlus -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> OrdPlus -> u
gmapQ :: (forall d. Data d => d -> u) -> OrdPlus -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> OrdPlus -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> OrdPlus -> r
gmapT :: (forall b. Data b => b -> b) -> OrdPlus -> OrdPlus
$cgmapT :: (forall b. Data b => b -> b) -> OrdPlus -> OrdPlus
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OrdPlus)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c OrdPlus)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c OrdPlus)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c OrdPlus)
dataTypeOf :: OrdPlus -> DataType
$cdataTypeOf :: OrdPlus -> DataType
toConstr :: OrdPlus -> Constr
$ctoConstr :: OrdPlus -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrdPlus
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c OrdPlus
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrdPlus -> c OrdPlus
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> OrdPlus -> c OrdPlus
$cp1Data :: Typeable OrdPlus
Data,Typeable)
data QueryOpt = QueryOptInAcctOnly AccountName
| QueryOptInAcct AccountName
deriving (Int -> QueryOpt -> ShowS
[QueryOpt] -> ShowS
QueryOpt -> String
(Int -> QueryOpt -> ShowS)
-> (QueryOpt -> String) -> ([QueryOpt] -> ShowS) -> Show QueryOpt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QueryOpt] -> ShowS
$cshowList :: [QueryOpt] -> ShowS
show :: QueryOpt -> String
$cshow :: QueryOpt -> String
showsPrec :: Int -> QueryOpt -> ShowS
$cshowsPrec :: Int -> QueryOpt -> ShowS
Show, QueryOpt -> QueryOpt -> Bool
(QueryOpt -> QueryOpt -> Bool)
-> (QueryOpt -> QueryOpt -> Bool) -> Eq QueryOpt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QueryOpt -> QueryOpt -> Bool
$c/= :: QueryOpt -> QueryOpt -> Bool
== :: QueryOpt -> QueryOpt -> Bool
$c== :: QueryOpt -> QueryOpt -> Bool
Eq, Typeable QueryOpt
Constr
DataType
Typeable QueryOpt =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> QueryOpt -> c QueryOpt)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c QueryOpt)
-> (QueryOpt -> Constr)
-> (QueryOpt -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c QueryOpt))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c QueryOpt))
-> ((forall b. Data b => b -> b) -> QueryOpt -> QueryOpt)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r)
-> (forall u. (forall d. Data d => d -> u) -> QueryOpt -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> QueryOpt -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt)
-> Data QueryOpt
QueryOpt -> Constr
QueryOpt -> DataType
(forall b. Data b => b -> b) -> QueryOpt -> QueryOpt
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> QueryOpt -> c QueryOpt
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c QueryOpt
forall a.
Typeable a =>
(forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> QueryOpt -> u
forall u. (forall d. Data d => d -> u) -> QueryOpt -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c QueryOpt
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> QueryOpt -> c QueryOpt
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c QueryOpt)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c QueryOpt)
$cQueryOptInAcct :: Constr
$cQueryOptInAcctOnly :: Constr
$tQueryOpt :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
gmapMp :: (forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
gmapM :: (forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> QueryOpt -> m QueryOpt
gmapQi :: Int -> (forall d. Data d => d -> u) -> QueryOpt -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> QueryOpt -> u
gmapQ :: (forall d. Data d => d -> u) -> QueryOpt -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> QueryOpt -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> QueryOpt -> r
gmapT :: (forall b. Data b => b -> b) -> QueryOpt -> QueryOpt
$cgmapT :: (forall b. Data b => b -> b) -> QueryOpt -> QueryOpt
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c QueryOpt)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c QueryOpt)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c QueryOpt)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c QueryOpt)
dataTypeOf :: QueryOpt -> DataType
$cdataTypeOf :: QueryOpt -> DataType
toConstr :: QueryOpt -> Constr
$ctoConstr :: QueryOpt -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c QueryOpt
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c QueryOpt
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> QueryOpt -> c QueryOpt
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> QueryOpt -> c QueryOpt
$cp1Data :: Typeable QueryOpt
Data, Typeable)
parseQuery :: Day -> T.Text -> (Query,[QueryOpt])
parseQuery :: Day -> Text -> (Query, [QueryOpt])
parseQuery d :: Day
d s :: Text
s = (Query
q, [QueryOpt]
opts)
where
terms :: [Text]
terms = [Text] -> Text -> [Text]
words'' [Text]
prefixes Text
s
(pats :: [Query]
pats, opts :: [QueryOpt]
opts) = [Either Query QueryOpt] -> ([Query], [QueryOpt])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either Query QueryOpt] -> ([Query], [QueryOpt]))
-> [Either Query QueryOpt] -> ([Query], [QueryOpt])
forall a b. (a -> b) -> a -> b
$ (Text -> Either Query QueryOpt)
-> [Text] -> [Either Query QueryOpt]
forall a b. (a -> b) -> [a] -> [b]
map (Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
d) [Text]
terms
(descpats :: [Query]
descpats, pats' :: [Query]
pats') = (Query -> Bool) -> [Query] -> ([Query], [Query])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Query -> Bool
queryIsDesc [Query]
pats
(acctpats :: [Query]
acctpats, pats'' :: [Query]
pats'') = (Query -> Bool) -> [Query] -> ([Query], [Query])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Query -> Bool
queryIsAcct [Query]
pats'
(statuspats :: [Query]
statuspats, otherpats :: [Query]
otherpats) = (Query -> Bool) -> [Query] -> ([Query], [Query])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Query -> Bool
queryIsStatus [Query]
pats''
q :: Query
q = Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And ([Query] -> Query) -> [Query] -> Query
forall a b. (a -> b) -> a -> b
$ [[Query] -> Query
Or [Query]
acctpats, [Query] -> Query
Or [Query]
descpats, [Query] -> Query
Or [Query]
statuspats] [Query] -> [Query] -> [Query]
forall a. [a] -> [a] -> [a]
++ [Query]
otherpats
words'' :: [T.Text] -> T.Text -> [T.Text]
words'' :: [Text] -> Text -> [Text]
words'' prefixes :: [Text]
prefixes = Either (ParseErrorBundle Text CustomErr) [Text] -> [Text]
forall t e a.
(Show t, Show (Token t), Show e) =>
Either (ParseErrorBundle t e) a -> a
fromparse (Either (ParseErrorBundle Text CustomErr) [Text] -> [Text])
-> (Text -> Either (ParseErrorBundle Text CustomErr) [Text])
-> Text
-> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parsec CustomErr Text [Text]
-> Text -> Either (ParseErrorBundle Text CustomErr) [Text]
forall e a.
Parsec e Text a -> Text -> Either (ParseErrorBundle Text e) a
parsewith Parsec CustomErr Text [Text]
maybeprefixedquotedphrases
where
maybeprefixedquotedphrases :: SimpleTextParser [T.Text]
maybeprefixedquotedphrases :: Parsec CustomErr Text [Text]
maybeprefixedquotedphrases = [TextParser Identity Text] -> TextParser Identity Text
forall (m :: * -> *) a. [TextParser m a] -> TextParser m a
choice' [TextParser Identity Text
prefixedQuotedPattern, TextParser Identity Text
singleQuotedPattern, TextParser Identity Text
doubleQuotedPattern, TextParser Identity Text
pattern] TextParser Identity Text
-> ParsecT CustomErr Text Identity ()
-> Parsec CustomErr Text [Text]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
`sepBy` ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity ()
forall (m :: * -> *) a. MonadPlus m => m a -> m ()
skipSome ParsecT CustomErr Text Identity Char
forall s (m :: * -> *).
(Stream s, Char ~ Token s) =>
ParsecT CustomErr s m Char
spacenonewline
prefixedQuotedPattern :: SimpleTextParser T.Text
prefixedQuotedPattern :: TextParser Identity Text
prefixedQuotedPattern = do
Text
not' <- Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe "" (Maybe Text -> Text)
-> ParsecT CustomErr Text Identity (Maybe Text)
-> TextParser Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` (TextParser Identity Text
-> ParsecT CustomErr Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (TextParser Identity Text
-> ParsecT CustomErr Text Identity (Maybe Text))
-> TextParser Identity Text
-> ParsecT CustomErr Text Identity (Maybe Text)
forall a b. (a -> b) -> a -> b
$ Tokens Text -> ParsecT CustomErr Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string "not:")
let allowednexts :: [Text]
allowednexts | Text -> Bool
T.null Text
not' = [Text]
prefixes
| Bool
otherwise = [Text]
prefixes [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [""]
Text
next <- [TextParser Identity Text] -> TextParser Identity Text
forall (m :: * -> *) a. [TextParser m a] -> TextParser m a
choice' ([TextParser Identity Text] -> TextParser Identity Text)
-> [TextParser Identity Text] -> TextParser Identity Text
forall a b. (a -> b) -> a -> b
$ (Text -> TextParser Identity Text)
-> [Text] -> [TextParser Identity Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> TextParser Identity Text
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string [Text]
allowednexts
let prefix :: T.Text
prefix :: Text
prefix = Text
not' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
next
Text
p <- TextParser Identity Text
singleQuotedPattern TextParser Identity Text
-> TextParser Identity Text -> TextParser Identity Text
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> TextParser Identity Text
doubleQuotedPattern
Text -> TextParser Identity Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> TextParser Identity Text)
-> Text -> TextParser Identity Text
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
stripquotes Text
p
singleQuotedPattern :: SimpleTextParser T.Text
singleQuotedPattern :: TextParser Identity Text
singleQuotedPattern = ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
-> ParsecT CustomErr Text Identity String
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT CustomErr Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Token Text
'\'') (Token Text -> ParsecT CustomErr Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Token Text
'\'') (ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String)
-> ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
forall a b. (a -> b) -> a -> b
$ [Token Text] -> ParsecT CustomErr Text Identity (Token Text)
forall (f :: * -> *) e s (m :: * -> *).
(Foldable f, MonadParsec e s m) =>
f (Token s) -> m (Token s)
noneOf ("'" :: [Char])) ParsecT CustomErr Text Identity String
-> (String -> TextParser Identity Text) -> TextParser Identity Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> TextParser Identity Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> TextParser Identity Text)
-> (String -> Text) -> String -> TextParser Identity Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
stripquotes (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
doubleQuotedPattern :: SimpleTextParser T.Text
doubleQuotedPattern :: TextParser Identity Text
doubleQuotedPattern = ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
-> ParsecT CustomErr Text Identity String
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT CustomErr Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Token Text
'"') (Token Text -> ParsecT CustomErr Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Token Text
'"') (ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String)
-> ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
forall a b. (a -> b) -> a -> b
$ [Token Text] -> ParsecT CustomErr Text Identity (Token Text)
forall (f :: * -> *) e s (m :: * -> *).
(Foldable f, MonadParsec e s m) =>
f (Token s) -> m (Token s)
noneOf ("\"" :: [Char])) ParsecT CustomErr Text Identity String
-> (String -> TextParser Identity Text) -> TextParser Identity Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> TextParser Identity Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> TextParser Identity Text)
-> (String -> Text) -> String -> TextParser Identity Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
stripquotes (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
pattern :: SimpleTextParser T.Text
pattern :: TextParser Identity Text
pattern = (String -> Text)
-> ParsecT CustomErr Text Identity String
-> TextParser Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
T.pack (ParsecT CustomErr Text Identity String
-> TextParser Identity Text)
-> ParsecT CustomErr Text Identity String
-> TextParser Identity Text
forall a b. (a -> b) -> a -> b
$ ParsecT CustomErr Text Identity Char
-> ParsecT CustomErr Text Identity String
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many ([Token Text] -> ParsecT CustomErr Text Identity (Token Text)
forall (f :: * -> *) e s (m :: * -> *).
(Foldable f, MonadParsec e s m) =>
f (Token s) -> m (Token s)
noneOf (" \n\r" :: [Char]))
prefixes :: [T.Text]
prefixes :: [Text]
prefixes = (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>":") [
"inacctonly"
,"inacct"
,"amt"
,"code"
,"desc"
,"payee"
,"note"
,"acct"
,"date"
,"date2"
,"status"
,"cur"
,"real"
,"empty"
,"depth"
,"tag"
]
defaultprefix :: T.Text
defaultprefix :: Text
defaultprefix = "acct"
parseQueryTerm :: Day -> T.Text -> Either Query QueryOpt
parseQueryTerm :: Day -> Text -> Either Query QueryOpt
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "inacctonly:" -> Just s :: Text
s) = QueryOpt -> Either Query QueryOpt
forall a b. b -> Either a b
Right (QueryOpt -> Either Query QueryOpt)
-> QueryOpt -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Text -> QueryOpt
QueryOptInAcctOnly Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "inacct:" -> Just s :: Text
s) = QueryOpt -> Either Query QueryOpt
forall a b. b -> Either a b
Right (QueryOpt -> Either Query QueryOpt)
-> QueryOpt -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Text -> QueryOpt
QueryOptInAcct Text
s
parseQueryTerm d :: Day
d (Text -> Text -> Maybe Text
T.stripPrefix "not:" -> Just s :: Text
s) =
case Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
d Text
s of
Left m :: Query
m -> Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Query -> Query
Not Query
m
Right _ -> Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left Query
Any
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "code:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Code (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "desc:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Desc (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "payee:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "payee" (Maybe String -> Query) -> Maybe String -> Query
forall a b. (a -> b) -> a -> b
$ String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "note:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "note" (Maybe String -> Query) -> Maybe String -> Query
forall a b. (a -> b) -> a -> b
$ String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "acct:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Acct (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
s
parseQueryTerm d :: Day
d (Text -> Text -> Maybe Text
T.stripPrefix "date2:" -> Just s :: Text
s) =
case Day
-> Text
-> Either (ParseErrorBundle Text CustomErr) (Interval, DateSpan)
parsePeriodExpr Day
d Text
s of Left e :: ParseErrorBundle Text CustomErr
e -> String -> Either Query QueryOpt
forall a. String -> a
error' (String -> Either Query QueryOpt)
-> String -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ "\"date2:"String -> ShowS
forall a. [a] -> [a] -> [a]
++Text -> String
T.unpack Text
sString -> ShowS
forall a. [a] -> [a] -> [a]
++"\" gave a "String -> ShowS
forall a. [a] -> [a] -> [a]
++ParseErrorBundle Text CustomErr -> String
forall t e.
(Show t, Show (Token t), Show e) =>
ParseErrorBundle t e -> String
showDateParseError ParseErrorBundle Text CustomErr
e
Right (_,span :: DateSpan
span) -> Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date2 DateSpan
span
parseQueryTerm d :: Day
d (Text -> Text -> Maybe Text
T.stripPrefix "date:" -> Just s :: Text
s) =
case Day
-> Text
-> Either (ParseErrorBundle Text CustomErr) (Interval, DateSpan)
parsePeriodExpr Day
d Text
s of Left e :: ParseErrorBundle Text CustomErr
e -> String -> Either Query QueryOpt
forall a. String -> a
error' (String -> Either Query QueryOpt)
-> String -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ "\"date:"String -> ShowS
forall a. [a] -> [a] -> [a]
++Text -> String
T.unpack Text
sString -> ShowS
forall a. [a] -> [a] -> [a]
++"\" gave a "String -> ShowS
forall a. [a] -> [a] -> [a]
++ParseErrorBundle Text CustomErr -> String
forall t e.
(Show t, Show (Token t), Show e) =>
ParseErrorBundle t e -> String
showDateParseError ParseErrorBundle Text CustomErr
e
Right (_,span :: DateSpan
span) -> Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date DateSpan
span
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "status:" -> Just s :: Text
s) =
case Text -> Either String Status
parseStatus Text
s of Left e :: String
e -> String -> Either Query QueryOpt
forall a. String -> a
error' (String -> Either Query QueryOpt)
-> String -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ "\"status:"String -> ShowS
forall a. [a] -> [a] -> [a]
++Text -> String
T.unpack Text
sString -> ShowS
forall a. [a] -> [a] -> [a]
++"\" gave a parse error: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
e
Right st :: Status
st -> Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
st
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "real:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Bool -> Query
Real (Bool -> Query) -> Bool -> Query
forall a b. (a -> b) -> a -> b
$ Text -> Bool
parseBool Text
s Bool -> Bool -> Bool
|| Text -> Bool
T.null Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "amt:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ OrdPlus -> Quantity -> Query
Amt OrdPlus
ord Quantity
q where (ord :: OrdPlus
ord, q :: Quantity
q) = Text -> (OrdPlus, Quantity)
parseAmountQueryTerm Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "empty:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Bool -> Query
Empty (Bool -> Query) -> Bool -> Query
forall a b. (a -> b) -> a -> b
$ Text -> Bool
parseBool Text
s
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "depth:" -> Just s :: Text
s)
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Int -> Query
Depth Int
n
| Bool
otherwise = String -> Either Query QueryOpt
forall a. String -> a
error' "depth: should have a positive number"
where n :: Int
n = Int -> String -> Int
forall a. Read a => a -> String -> a
readDef 0 (Text -> String
T.unpack Text
s)
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "cur:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Sym (Text -> String
T.unpack Text
s)
parseQueryTerm _ (Text -> Text -> Maybe Text
T.stripPrefix "tag:" -> Just s :: Text
s) = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag String
n Maybe String
v where (n :: String
n,v :: Maybe String
v) = Text -> (String, Maybe String)
parseTag Text
s
parseQueryTerm _ "" = Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Query
Any
parseQueryTerm d :: Day
d s :: Text
s = Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
d (Text -> Either Query QueryOpt) -> Text -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Text
defaultprefixText -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>":"Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>Text
s
parseAmountQueryTerm :: T.Text -> (OrdPlus, Quantity)
parseAmountQueryTerm :: Text -> (OrdPlus, Quantity)
parseAmountQueryTerm s' :: Text
s' =
case Text
s' of
"" -> (OrdPlus, Quantity)
forall a. a
err
(Text -> Text -> Maybe Text
T.stripPrefix "<+" -> Just s :: Text
s) -> (OrdPlus
Lt, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "<=+" -> Just s :: Text
s) -> (OrdPlus
LtEq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix ">+" -> Just s :: Text
s) -> (OrdPlus
Gt, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix ">=+" -> Just s :: Text
s) -> (OrdPlus
GtEq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "=+" -> Just s :: Text
s) -> (OrdPlus
Eq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "+" -> Just s :: Text
s) -> (OrdPlus
Eq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "<-" -> Just s :: Text
s) -> (OrdPlus
Lt, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "<=-" -> Just s :: Text
s) -> (OrdPlus
LtEq, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix ">-" -> Just s :: Text
s) -> (OrdPlus
Gt, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix ">=-" -> Just s :: Text
s) -> (OrdPlus
GtEq, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "=-" -> Just s :: Text
s) -> (OrdPlus
Eq, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "-" -> Just s :: Text
s) -> (OrdPlus
Eq, Quantity -> Quantity
forall a. Num a => a -> a
negate (Quantity -> Quantity) -> Quantity -> Quantity
forall a b. (a -> b) -> a -> b
$ Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
(Text -> Text -> Maybe Text
T.stripPrefix "<=" -> Just s :: Text
s) -> let n :: Quantity
n = Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s) in
case Quantity
n of
0 -> (OrdPlus
LtEq, 0)
_ -> (OrdPlus
AbsLtEq, Quantity
n)
(Text -> Text -> Maybe Text
T.stripPrefix "<" -> Just s :: Text
s) -> let n :: Quantity
n = Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s) in
case Quantity
n of 0 -> (OrdPlus
Lt, 0)
_ -> (OrdPlus
AbsLt, Quantity
n)
(Text -> Text -> Maybe Text
T.stripPrefix ">=" -> Just s :: Text
s) -> let n :: Quantity
n = Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s) in
case Quantity
n of 0 -> (OrdPlus
GtEq, 0)
_ -> (OrdPlus
AbsGtEq, Quantity
n)
(Text -> Text -> Maybe Text
T.stripPrefix ">" -> Just s :: Text
s) -> let n :: Quantity
n = Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s) in
case Quantity
n of 0 -> (OrdPlus
Gt, 0)
_ -> (OrdPlus
AbsGt, Quantity
n)
(Text -> Text -> Maybe Text
T.stripPrefix "=" -> Just s :: Text
s) -> (OrdPlus
AbsEq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
s :: Text
s -> (OrdPlus
AbsEq, Quantity -> String -> Quantity
forall a. Read a => a -> String -> a
readDef Quantity
forall a. a
err (Text -> String
T.unpack Text
s))
where
err :: a
err = String -> a
forall a. String -> a
error' (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ "could not parse as '=', '<', or '>' (optional) followed by a (optionally signed) numeric quantity: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
s'
parseTag :: T.Text -> (Regexp, Maybe Regexp)
parseTag :: Text -> (String, Maybe String)
parseTag s :: Text
s | "=" Text -> Text -> Bool
`T.isInfixOf` Text
s = (Text -> String
T.unpack Text
n, String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ ShowS
forall a. [a] -> [a]
tail ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
v)
| Bool
otherwise = (Text -> String
T.unpack Text
s, Maybe String
forall a. Maybe a
Nothing)
where (n :: Text
n,v :: Text
v) = (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
=='=') Text
s
parseStatus :: T.Text -> Either String Status
parseStatus :: Text -> Either String Status
parseStatus s :: Text
s | Text
s Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["*","1"] = Status -> Either String Status
forall a b. b -> Either a b
Right Status
Cleared
| Text
s Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["!"] = Status -> Either String Status
forall a b. b -> Either a b
Right Status
Pending
| Text
s Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ["","0"] = Status -> Either String Status
forall a b. b -> Either a b
Right Status
Unmarked
| Bool
otherwise = String -> Either String Status
forall a b. a -> Either a b
Left (String -> Either String Status) -> String -> Either String Status
forall a b. (a -> b) -> a -> b
$ "could not parse "String -> ShowS
forall a. [a] -> [a] -> [a]
++Text -> String
forall a. Show a => a -> String
show Text
sString -> ShowS
forall a. [a] -> [a] -> [a]
++" as a status (should be *, ! or empty)"
parseBool :: T.Text -> Bool
parseBool :: Text -> Bool
parseBool s :: Text
s = Text
s Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
truestrings
truestrings :: [T.Text]
truestrings :: [Text]
truestrings = ["1"]
simplifyQuery :: Query -> Query
simplifyQuery :: Query -> Query
simplifyQuery q :: Query
q =
let q' :: Query
q' = Query -> Query
simplify Query
q
in if Query
q' Query -> Query -> Bool
forall a. Eq a => a -> a -> Bool
== Query
q then Query
q else Query -> Query
simplifyQuery Query
q'
where
simplify :: Query -> Query
simplify (And []) = Query
Any
simplify (And [q :: Query
q]) = Query -> Query
simplify Query
q
simplify (And qs :: [Query]
qs) | [Query] -> Bool
forall a. Eq a => [a] -> Bool
same [Query]
qs = Query -> Query
simplify (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
forall a. [a] -> a
head [Query]
qs
| (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Query -> Bool
forall a. Eq a => a -> a -> Bool
==Query
None) [Query]
qs = Query
None
| (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Query -> Bool
queryIsDate [Query]
qs = DateSpan -> Query
Date (DateSpan -> Query) -> DateSpan -> Query
forall a b. (a -> b) -> a -> b
$ [DateSpan] -> DateSpan
spansIntersect ([DateSpan] -> DateSpan) -> [DateSpan] -> DateSpan
forall a b. (a -> b) -> a -> b
$ (Query -> Maybe DateSpan) -> [Query] -> [DateSpan]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Query -> Maybe DateSpan
queryTermDateSpan [Query]
qs
| Bool
otherwise = [Query] -> Query
And ([Query] -> Query) -> [Query] -> Query
forall a b. (a -> b) -> a -> b
$ [[Query]] -> [Query]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Query]] -> [Query]) -> [[Query]] -> [Query]
forall a b. (a -> b) -> a -> b
$ [(Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map Query -> Query
simplify [Query]
dateqs, (Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map Query -> Query
simplify [Query]
otherqs]
where (dateqs :: [Query]
dateqs, otherqs :: [Query]
otherqs) = (Query -> Bool) -> [Query] -> ([Query], [Query])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition Query -> Bool
queryIsDate ([Query] -> ([Query], [Query])) -> [Query] -> ([Query], [Query])
forall a b. (a -> b) -> a -> b
$ (Query -> Bool) -> [Query] -> [Query]
forall a. (a -> Bool) -> [a] -> [a]
filter (Query -> Query -> Bool
forall a. Eq a => a -> a -> Bool
/=Query
Any) [Query]
qs
simplify (Or []) = Query
Any
simplify (Or [q :: Query
q]) = Query -> Query
simplifyQuery Query
q
simplify (Or qs :: [Query]
qs) | [Query] -> Bool
forall a. Eq a => [a] -> Bool
same [Query]
qs = Query -> Query
simplify (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
forall a. [a] -> a
head [Query]
qs
| (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Query -> Bool
forall a. Eq a => a -> a -> Bool
==Query
Any) [Query]
qs = Query
Any
| Bool
otherwise = [Query] -> Query
Or ([Query] -> Query) -> [Query] -> Query
forall a b. (a -> b) -> a -> b
$ (Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map Query -> Query
simplify ([Query] -> [Query]) -> [Query] -> [Query]
forall a b. (a -> b) -> a -> b
$ (Query -> Bool) -> [Query] -> [Query]
forall a. (a -> Bool) -> [a] -> [a]
filter (Query -> Query -> Bool
forall a. Eq a => a -> a -> Bool
/=Query
None) [Query]
qs
simplify (Date (DateSpan Nothing Nothing)) = Query
Any
simplify (Date2 (DateSpan Nothing Nothing)) = Query
Any
simplify q :: Query
q = Query
q
same :: [a] -> Bool
same [] = Bool
True
same (a :: a
a:as :: [a]
as) = (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (a
aa -> a -> Bool
forall a. Eq a => a -> a -> Bool
==) [a]
as
filterQuery :: (Query -> Bool) -> Query -> Query
filterQuery :: (Query -> Bool) -> Query -> Query
filterQuery p :: Query -> Bool
p = Query -> Query
simplifyQuery (Query -> Query) -> (Query -> Query) -> Query -> Query
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Query -> Bool) -> Query -> Query
filterQuery' Query -> Bool
p
filterQuery' :: (Query -> Bool) -> Query -> Query
filterQuery' :: (Query -> Bool) -> Query -> Query
filterQuery' p :: Query -> Bool
p (And qs :: [Query]
qs) = [Query] -> Query
And ([Query] -> Query) -> [Query] -> Query
forall a b. (a -> b) -> a -> b
$ (Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map ((Query -> Bool) -> Query -> Query
filterQuery Query -> Bool
p) [Query]
qs
filterQuery' p :: Query -> Bool
p (Or qs :: [Query]
qs) = [Query] -> Query
Or ([Query] -> Query) -> [Query] -> Query
forall a b. (a -> b) -> a -> b
$ (Query -> Query) -> [Query] -> [Query]
forall a b. (a -> b) -> [a] -> [b]
map ((Query -> Bool) -> Query -> Query
filterQuery Query -> Bool
p) [Query]
qs
filterQuery' p :: Query -> Bool
p q :: Query
q = if Query -> Bool
p Query
q then Query
q else Query
Any
queryIsNull :: Query -> Bool
queryIsNull :: Query -> Bool
queryIsNull Any = Bool
True
queryIsNull (And []) = Bool
True
queryIsNull (Not (Or [])) = Bool
True
queryIsNull _ = Bool
False
queryIsDepth :: Query -> Bool
queryIsDepth :: Query -> Bool
queryIsDepth (Depth _) = Bool
True
queryIsDepth _ = Bool
False
queryIsDate :: Query -> Bool
queryIsDate :: Query -> Bool
queryIsDate (Date _) = Bool
True
queryIsDate _ = Bool
False
queryIsDate2 :: Query -> Bool
queryIsDate2 :: Query -> Bool
queryIsDate2 (Date2 _) = Bool
True
queryIsDate2 _ = Bool
False
queryIsDateOrDate2 :: Query -> Bool
queryIsDateOrDate2 :: Query -> Bool
queryIsDateOrDate2 (Date _) = Bool
True
queryIsDateOrDate2 (Date2 _) = Bool
True
queryIsDateOrDate2 _ = Bool
False
queryIsDesc :: Query -> Bool
queryIsDesc :: Query -> Bool
queryIsDesc (Desc _) = Bool
True
queryIsDesc _ = Bool
False
queryIsAcct :: Query -> Bool
queryIsAcct :: Query -> Bool
queryIsAcct (Acct _) = Bool
True
queryIsAcct _ = Bool
False
queryIsAmt :: Query -> Bool
queryIsAmt :: Query -> Bool
queryIsAmt (Amt _ _) = Bool
True
queryIsAmt _ = Bool
False
queryIsSym :: Query -> Bool
queryIsSym :: Query -> Bool
queryIsSym (Sym _) = Bool
True
queryIsSym _ = Bool
False
queryIsReal :: Query -> Bool
queryIsReal :: Query -> Bool
queryIsReal (Real _) = Bool
True
queryIsReal _ = Bool
False
queryIsStatus :: Query -> Bool
queryIsStatus :: Query -> Bool
queryIsStatus (StatusQ _) = Bool
True
queryIsStatus _ = Bool
False
queryIsEmpty :: Query -> Bool
queryIsEmpty :: Query -> Bool
queryIsEmpty (Empty _) = Bool
True
queryIsEmpty _ = Bool
False
queryIsStartDateOnly :: Bool -> Query -> Bool
queryIsStartDateOnly :: Bool -> Query -> Bool
queryIsStartDateOnly _ Any = Bool
False
queryIsStartDateOnly _ None = Bool
False
queryIsStartDateOnly secondary :: Bool
secondary (Or ms :: [Query]
ms) = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> [Bool] -> Bool
forall a b. (a -> b) -> a -> b
$ (Query -> Bool) -> [Query] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Bool
queryIsStartDateOnly Bool
secondary) [Query]
ms
queryIsStartDateOnly secondary :: Bool
secondary (And ms :: [Query]
ms) = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ([Bool] -> Bool) -> [Bool] -> Bool
forall a b. (a -> b) -> a -> b
$ (Query -> Bool) -> [Query] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Bool
queryIsStartDateOnly Bool
secondary) [Query]
ms
queryIsStartDateOnly False (Date (DateSpan (Just _) _)) = Bool
True
queryIsStartDateOnly True (Date2 (DateSpan (Just _) _)) = Bool
True
queryIsStartDateOnly _ _ = Bool
False
queryStartDate :: Bool -> Query -> Maybe Day
queryStartDate :: Bool -> Query -> Maybe Day
queryStartDate secondary :: Bool
secondary (Or ms :: [Query]
ms) = [Maybe Day] -> Maybe Day
earliestMaybeDate ([Maybe Day] -> Maybe Day) -> [Maybe Day] -> Maybe Day
forall a b. (a -> b) -> a -> b
$ (Query -> Maybe Day) -> [Query] -> [Maybe Day]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Maybe Day
queryStartDate Bool
secondary) [Query]
ms
queryStartDate secondary :: Bool
secondary (And ms :: [Query]
ms) = [Maybe Day] -> Maybe Day
latestMaybeDate ([Maybe Day] -> Maybe Day) -> [Maybe Day] -> Maybe Day
forall a b. (a -> b) -> a -> b
$ (Query -> Maybe Day) -> [Query] -> [Maybe Day]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Maybe Day
queryStartDate Bool
secondary) [Query]
ms
queryStartDate False (Date (DateSpan (Just d :: Day
d) _)) = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
d
queryStartDate True (Date2 (DateSpan (Just d :: Day
d) _)) = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
d
queryStartDate _ _ = Maybe Day
forall a. Maybe a
Nothing
queryEndDate :: Bool -> Query -> Maybe Day
queryEndDate :: Bool -> Query -> Maybe Day
queryEndDate secondary :: Bool
secondary (Or ms :: [Query]
ms) = [Maybe Day] -> Maybe Day
latestMaybeDate' ([Maybe Day] -> Maybe Day) -> [Maybe Day] -> Maybe Day
forall a b. (a -> b) -> a -> b
$ (Query -> Maybe Day) -> [Query] -> [Maybe Day]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Maybe Day
queryEndDate Bool
secondary) [Query]
ms
queryEndDate secondary :: Bool
secondary (And ms :: [Query]
ms) = [Maybe Day] -> Maybe Day
earliestMaybeDate' ([Maybe Day] -> Maybe Day) -> [Maybe Day] -> Maybe Day
forall a b. (a -> b) -> a -> b
$ (Query -> Maybe Day) -> [Query] -> [Maybe Day]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> Maybe Day
queryEndDate Bool
secondary) [Query]
ms
queryEndDate False (Date (DateSpan _ (Just d :: Day
d))) = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
d
queryEndDate True (Date2 (DateSpan _ (Just d :: Day
d))) = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
d
queryEndDate _ _ = Maybe Day
forall a. Maybe a
Nothing
queryTermDateSpan :: Query -> Maybe DateSpan
queryTermDateSpan (Date span :: DateSpan
span) = DateSpan -> Maybe DateSpan
forall a. a -> Maybe a
Just DateSpan
span
queryTermDateSpan _ = Maybe DateSpan
forall a. Maybe a
Nothing
queryDateSpan :: Bool -> Query -> DateSpan
queryDateSpan :: Bool -> Query -> DateSpan
queryDateSpan secondary :: Bool
secondary (Or qs :: [Query]
qs) = [DateSpan] -> DateSpan
spansUnion ([DateSpan] -> DateSpan) -> [DateSpan] -> DateSpan
forall a b. (a -> b) -> a -> b
$ (Query -> DateSpan) -> [Query] -> [DateSpan]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> DateSpan
queryDateSpan Bool
secondary) [Query]
qs
queryDateSpan secondary :: Bool
secondary (And qs :: [Query]
qs) = [DateSpan] -> DateSpan
spansIntersect ([DateSpan] -> DateSpan) -> [DateSpan] -> DateSpan
forall a b. (a -> b) -> a -> b
$ (Query -> DateSpan) -> [Query] -> [DateSpan]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> Query -> DateSpan
queryDateSpan Bool
secondary) [Query]
qs
queryDateSpan False (Date span :: DateSpan
span) = DateSpan
span
queryDateSpan True (Date2 span :: DateSpan
span) = DateSpan
span
queryDateSpan _ _ = DateSpan
nulldatespan
queryDateSpan' :: Query -> DateSpan
queryDateSpan' :: Query -> DateSpan
queryDateSpan' (Or qs :: [Query]
qs) = [DateSpan] -> DateSpan
spansUnion ([DateSpan] -> DateSpan) -> [DateSpan] -> DateSpan
forall a b. (a -> b) -> a -> b
$ (Query -> DateSpan) -> [Query] -> [DateSpan]
forall a b. (a -> b) -> [a] -> [b]
map Query -> DateSpan
queryDateSpan' [Query]
qs
queryDateSpan' (And qs :: [Query]
qs) = [DateSpan] -> DateSpan
spansIntersect ([DateSpan] -> DateSpan) -> [DateSpan] -> DateSpan
forall a b. (a -> b) -> a -> b
$ (Query -> DateSpan) -> [Query] -> [DateSpan]
forall a b. (a -> b) -> [a] -> [b]
map Query -> DateSpan
queryDateSpan' [Query]
qs
queryDateSpan' (Date span :: DateSpan
span) = DateSpan
span
queryDateSpan' (Date2 span :: DateSpan
span) = DateSpan
span
queryDateSpan' _ = DateSpan
nulldatespan
earliestMaybeDate :: [Maybe Day] -> Maybe Day
earliestMaybeDate :: [Maybe Day] -> Maybe Day
earliestMaybeDate mds :: [Maybe Day]
mds = [Maybe Day] -> Maybe Day
forall a. [a] -> a
head ([Maybe Day] -> Maybe Day) -> [Maybe Day] -> Maybe Day
forall a b. (a -> b) -> a -> b
$ (Maybe Day -> Maybe Day -> Ordering) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy Maybe Day -> Maybe Day -> Ordering
compareMaybeDates [Maybe Day]
mds [Maybe Day] -> [Maybe Day] -> [Maybe Day]
forall a. [a] -> [a] -> [a]
++ [Maybe Day
forall a. Maybe a
Nothing]
latestMaybeDate :: [Maybe Day] -> Maybe Day
latestMaybeDate :: [Maybe Day] -> Maybe Day
latestMaybeDate = Maybe Day -> [Maybe Day] -> Maybe Day
forall a. a -> [a] -> a
headDef Maybe Day
forall a. Maybe a
Nothing ([Maybe Day] -> Maybe Day)
-> ([Maybe Day] -> [Maybe Day]) -> [Maybe Day] -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Day -> Maybe Day -> Ordering) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((Maybe Day -> Maybe Day -> Ordering)
-> Maybe Day -> Maybe Day -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip Maybe Day -> Maybe Day -> Ordering
compareMaybeDates)
earliestMaybeDate' :: [Maybe Day] -> Maybe Day
earliestMaybeDate' :: [Maybe Day] -> Maybe Day
earliestMaybeDate' = Maybe Day -> [Maybe Day] -> Maybe Day
forall a. a -> [a] -> a
headDef Maybe Day
forall a. Maybe a
Nothing ([Maybe Day] -> Maybe Day)
-> ([Maybe Day] -> [Maybe Day]) -> [Maybe Day] -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Day -> Maybe Day -> Ordering) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy Maybe Day -> Maybe Day -> Ordering
compareMaybeDates ([Maybe Day] -> [Maybe Day])
-> ([Maybe Day] -> [Maybe Day]) -> [Maybe Day] -> [Maybe Day]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Day -> Bool) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> Bool) -> [a] -> [a]
filter Maybe Day -> Bool
forall a. Maybe a -> Bool
isJust
latestMaybeDate' :: [Maybe Day] -> Maybe Day
latestMaybeDate' :: [Maybe Day] -> Maybe Day
latestMaybeDate' = Maybe Day -> [Maybe Day] -> Maybe Day
forall a. a -> [a] -> a
headDef Maybe Day
forall a. Maybe a
Nothing ([Maybe Day] -> Maybe Day)
-> ([Maybe Day] -> [Maybe Day]) -> [Maybe Day] -> Maybe Day
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Day -> Maybe Day -> Ordering) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ((Maybe Day -> Maybe Day -> Ordering)
-> Maybe Day -> Maybe Day -> Ordering
forall a b c. (a -> b -> c) -> b -> a -> c
flip Maybe Day -> Maybe Day -> Ordering
compareMaybeDates) ([Maybe Day] -> [Maybe Day])
-> ([Maybe Day] -> [Maybe Day]) -> [Maybe Day] -> [Maybe Day]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Day -> Bool) -> [Maybe Day] -> [Maybe Day]
forall a. (a -> Bool) -> [a] -> [a]
filter Maybe Day -> Bool
forall a. Maybe a -> Bool
isJust
compareMaybeDates :: Maybe Day -> Maybe Day -> Ordering
compareMaybeDates :: Maybe Day -> Maybe Day -> Ordering
compareMaybeDates Nothing Nothing = Ordering
EQ
compareMaybeDates Nothing (Just _) = Ordering
LT
compareMaybeDates (Just _) Nothing = Ordering
GT
compareMaybeDates (Just a :: Day
a) (Just b :: Day
b) = Day -> Day -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Day
a Day
b
queryDepth :: Query -> Int
queryDepth :: Query -> Int
queryDepth q :: Query
q = case Query -> [Int]
queryDepth' Query
q of [] -> 99999
ds :: [Int]
ds -> [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum [Int]
ds
where
queryDepth' :: Query -> [Int]
queryDepth' (Depth d :: Int
d) = [Int
d]
queryDepth' (Or qs :: [Query]
qs) = (Query -> [Int]) -> [Query] -> [Int]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Query -> [Int]
queryDepth' [Query]
qs
queryDepth' (And qs :: [Query]
qs) = (Query -> [Int]) -> [Query] -> [Int]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Query -> [Int]
queryDepth' [Query]
qs
queryDepth' _ = []
inAccount :: [QueryOpt] -> Maybe (AccountName,Bool)
inAccount :: [QueryOpt] -> Maybe (Text, Bool)
inAccount [] = Maybe (Text, Bool)
forall a. Maybe a
Nothing
inAccount (QueryOptInAcctOnly a :: Text
a:_) = (Text, Bool) -> Maybe (Text, Bool)
forall a. a -> Maybe a
Just (Text
a,Bool
False)
inAccount (QueryOptInAcct a :: Text
a:_) = (Text, Bool) -> Maybe (Text, Bool)
forall a. a -> Maybe a
Just (Text
a,Bool
True)
inAccountQuery :: [QueryOpt] -> Maybe Query
inAccountQuery :: [QueryOpt] -> Maybe Query
inAccountQuery [] = Maybe Query
forall a. Maybe a
Nothing
inAccountQuery (QueryOptInAcctOnly a :: Text
a : _) = Query -> Maybe Query
forall a. a -> Maybe a
Just (Query -> Maybe Query) -> Query -> Maybe Query
forall a b. (a -> b) -> a -> b
$ String -> Query
Acct (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
accountNameToAccountOnlyRegex Text
a
inAccountQuery (QueryOptInAcct a :: Text
a : _) = Query -> Maybe Query
forall a. a -> Maybe a
Just (Query -> Maybe Query) -> Query -> Maybe Query
forall a b. (a -> b) -> a -> b
$ String -> Query
Acct (String -> Query) -> String -> Query
forall a b. (a -> b) -> a -> b
$ Text -> String
accountNameToAccountRegex Text
a
matchesAccount :: Query -> AccountName -> Bool
matchesAccount :: Query -> Text -> Bool
matchesAccount (Query
None) _ = Bool
False
matchesAccount (Not m :: Query
m) a :: Text
a = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Query -> Text -> Bool
matchesAccount Query
m Text
a
matchesAccount (Or ms :: [Query]
ms) a :: Text
a = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Text -> Bool
`matchesAccount` Text
a) [Query]
ms
matchesAccount (And ms :: [Query]
ms) a :: Text
a = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Query -> Text -> Bool
`matchesAccount` Text
a) [Query]
ms
matchesAccount (Acct r :: String
r) a :: Text
a = String -> String -> Bool
regexMatchesCI String
r (Text -> String
T.unpack Text
a)
matchesAccount (Depth d :: Int
d) a :: Text
a = Text -> Int
accountNameLevel Text
a Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
d
matchesAccount (Tag _ _) _ = Bool
False
matchesAccount _ _ = Bool
True
matchesMixedAmount :: Query -> MixedAmount -> Bool
matchesMixedAmount :: Query -> MixedAmount -> Bool
matchesMixedAmount q :: Query
q (Mixed []) = Query
q Query -> Amount -> Bool
`matchesAmount` Amount
nullamt
matchesMixedAmount q :: Query
q (Mixed as :: [Amount]
as) = (Amount -> Bool) -> [Amount] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query
q Query -> Amount -> Bool
`matchesAmount`) [Amount]
as
matchesCommodity :: Query -> CommoditySymbol -> Bool
matchesCommodity :: Query -> Text -> Bool
matchesCommodity (Sym r :: String
r) s :: Text
s = String -> String -> Bool
regexMatchesCI ("^" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ "$") (Text -> String
T.unpack Text
s)
matchesCommodity _ _ = Bool
True
matchesAmount :: Query -> Amount -> Bool
matchesAmount :: Query -> Amount -> Bool
matchesAmount (Not q :: Query
q) a :: Amount
a = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Query
q Query -> Amount -> Bool
`matchesAmount` Amount
a
matchesAmount (Query
Any) _ = Bool
True
matchesAmount (Query
None) _ = Bool
False
matchesAmount (Or qs :: [Query]
qs) a :: Amount
a = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Amount -> Bool
`matchesAmount` Amount
a) [Query]
qs
matchesAmount (And qs :: [Query]
qs) a :: Amount
a = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Query -> Amount -> Bool
`matchesAmount` Amount
a) [Query]
qs
matchesAmount (Amt ord :: OrdPlus
ord n :: Quantity
n) a :: Amount
a = OrdPlus -> Quantity -> Amount -> Bool
compareAmount OrdPlus
ord Quantity
n Amount
a
matchesAmount (Sym r :: String
r) a :: Amount
a = Query -> Text -> Bool
matchesCommodity (String -> Query
Sym String
r) (Amount -> Text
acommodity Amount
a)
matchesAmount _ _ = Bool
True
compareAmount :: OrdPlus -> Quantity -> Amount -> Bool
compareAmount :: OrdPlus -> Quantity -> Amount -> Bool
compareAmount ord :: OrdPlus
ord q :: Quantity
q Amount{aquantity :: Amount -> Quantity
aquantity=Quantity
aq} = case OrdPlus
ord of Lt -> Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
< Quantity
q
LtEq -> Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
<= Quantity
q
Gt -> Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
> Quantity
q
GtEq -> Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
>= Quantity
q
Eq -> Quantity
aq Quantity -> Quantity -> Bool
forall a. Eq a => a -> a -> Bool
== Quantity
q
AbsLt -> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
< Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
q
AbsLtEq -> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
<= Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
q
AbsGt -> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
q
AbsGtEq -> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
aq Quantity -> Quantity -> Bool
forall a. Ord a => a -> a -> Bool
>= Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
q
AbsEq -> Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
aq Quantity -> Quantity -> Bool
forall a. Eq a => a -> a -> Bool
== Quantity -> Quantity
forall a. Num a => a -> a
abs Quantity
q
matchesPosting :: Query -> Posting -> Bool
matchesPosting :: Query -> Posting -> Bool
matchesPosting (Not q :: Query
q) p :: Posting
p = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Query
q Query -> Posting -> Bool
`matchesPosting` Posting
p
matchesPosting (Query
Any) _ = Bool
True
matchesPosting (Query
None) _ = Bool
False
matchesPosting (Or qs :: [Query]
qs) p :: Posting
p = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Posting -> Bool
`matchesPosting` Posting
p) [Query]
qs
matchesPosting (And qs :: [Query]
qs) p :: Posting
p = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Query -> Posting -> Bool
`matchesPosting` Posting
p) [Query]
qs
matchesPosting (Code r :: String
r) p :: Posting
p = String -> String -> Bool
regexMatchesCI String
r (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String -> (Transaction -> String) -> Maybe Transaction -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "" (Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
tcode) (Maybe Transaction -> String) -> Maybe Transaction -> String
forall a b. (a -> b) -> a -> b
$ Posting -> Maybe Transaction
ptransaction Posting
p
matchesPosting (Desc r :: String
r) p :: Posting
p = String -> String -> Bool
regexMatchesCI String
r (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String -> (Transaction -> String) -> Maybe Transaction -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "" (Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
tdescription) (Maybe Transaction -> String) -> Maybe Transaction -> String
forall a b. (a -> b) -> a -> b
$ Posting -> Maybe Transaction
ptransaction Posting
p
matchesPosting (Acct r :: String
r) p :: Posting
p = Posting -> Bool
matchesPosting Posting
p Bool -> Bool -> Bool
|| Posting -> Bool
matchesPosting (Posting -> Posting
originalPosting Posting
p)
where matchesPosting :: Posting -> Bool
matchesPosting p :: Posting
p = String -> String -> Bool
regexMatchesCI String
r (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Posting -> Text
paccount Posting
p
matchesPosting (Date span :: DateSpan
span) p :: Posting
p = DateSpan
span DateSpan -> Day -> Bool
`spanContainsDate` Posting -> Day
postingDate Posting
p
matchesPosting (Date2 span :: DateSpan
span) p :: Posting
p = DateSpan
span DateSpan -> Day -> Bool
`spanContainsDate` Posting -> Day
postingDate2 Posting
p
matchesPosting (StatusQ s :: Status
s) p :: Posting
p = Posting -> Status
postingStatus Posting
p Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
== Status
s
matchesPosting (Real v :: Bool
v) p :: Posting
p = Bool
v Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Posting -> Bool
isReal Posting
p
matchesPosting q :: Query
q@(Depth _) Posting{paccount :: Posting -> Text
paccount=Text
a} = Query
q Query -> Text -> Bool
`matchesAccount` Text
a
matchesPosting q :: Query
q@(Amt _ _) Posting{pamount :: Posting -> MixedAmount
pamount=MixedAmount
amt} = Query
q Query -> MixedAmount -> Bool
`matchesMixedAmount` MixedAmount
amt
matchesPosting (Empty _) _ = Bool
True
matchesPosting (Sym r :: String
r) Posting{pamount :: Posting -> MixedAmount
pamount=Mixed as :: [Amount]
as} = (Text -> Bool) -> [Text] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Text -> Bool
matchesCommodity (String -> Query
Sym String
r)) ([Text] -> Bool) -> [Text] -> Bool
forall a b. (a -> b) -> a -> b
$ (Amount -> Text) -> [Amount] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Amount -> Text
acommodity [Amount]
as
matchesPosting (Tag n :: String
n v :: Maybe String
v) p :: Posting
p = case (String
n, Maybe String
v) of
("payee", Just v :: String
v) -> Bool -> (Transaction -> Bool) -> Maybe Transaction -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (String -> String -> Bool
regexMatchesCI String
v (String -> Bool) -> (Transaction -> String) -> Transaction -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
transactionPayee) (Maybe Transaction -> Bool) -> Maybe Transaction -> Bool
forall a b. (a -> b) -> a -> b
$ Posting -> Maybe Transaction
ptransaction Posting
p
("note", Just v :: String
v) -> Bool -> (Transaction -> Bool) -> Maybe Transaction -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (String -> String -> Bool
regexMatchesCI String
v (String -> Bool) -> (Transaction -> String) -> Transaction -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
transactionNote) (Maybe Transaction -> Bool) -> Maybe Transaction -> Bool
forall a b. (a -> b) -> a -> b
$ Posting -> Maybe Transaction
ptransaction Posting
p
(n :: String
n, v :: Maybe String
v) -> String -> Maybe String -> [(Text, Text)] -> Bool
matchesTags String
n Maybe String
v ([(Text, Text)] -> Bool) -> [(Text, Text)] -> Bool
forall a b. (a -> b) -> a -> b
$ Posting -> [(Text, Text)]
postingAllTags Posting
p
matchesTransaction :: Query -> Transaction -> Bool
matchesTransaction :: Query -> Transaction -> Bool
matchesTransaction (Not q :: Query
q) t :: Transaction
t = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Query
q Query -> Transaction -> Bool
`matchesTransaction` Transaction
t
matchesTransaction (Query
Any) _ = Bool
True
matchesTransaction (Query
None) _ = Bool
False
matchesTransaction (Or qs :: [Query]
qs) t :: Transaction
t = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> Transaction -> Bool
`matchesTransaction` Transaction
t) [Query]
qs
matchesTransaction (And qs :: [Query]
qs) t :: Transaction
t = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Query -> Transaction -> Bool
`matchesTransaction` Transaction
t) [Query]
qs
matchesTransaction (Code r :: String
r) t :: Transaction
t = String -> String -> Bool
regexMatchesCI String
r (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Transaction -> Text
tcode Transaction
t
matchesTransaction (Desc r :: String
r) t :: Transaction
t = String -> String -> Bool
regexMatchesCI String
r (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Transaction -> Text
tdescription Transaction
t
matchesTransaction q :: Query
q@(Acct _) t :: Transaction
t = (Posting -> Bool) -> [Posting] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query
q Query -> Posting -> Bool
`matchesPosting`) ([Posting] -> Bool) -> [Posting] -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> [Posting]
tpostings Transaction
t
matchesTransaction (Date span :: DateSpan
span) t :: Transaction
t = DateSpan -> Day -> Bool
spanContainsDate DateSpan
span (Day -> Bool) -> Day -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> Day
tdate Transaction
t
matchesTransaction (Date2 span :: DateSpan
span) t :: Transaction
t = DateSpan -> Day -> Bool
spanContainsDate DateSpan
span (Day -> Bool) -> Day -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> Day
transactionDate2 Transaction
t
matchesTransaction (StatusQ s :: Status
s) t :: Transaction
t = Transaction -> Status
tstatus Transaction
t Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
== Status
s
matchesTransaction (Real v :: Bool
v) t :: Transaction
t = Bool
v Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Transaction -> Bool
hasRealPostings Transaction
t
matchesTransaction q :: Query
q@(Amt _ _) t :: Transaction
t = (Posting -> Bool) -> [Posting] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query
q Query -> Posting -> Bool
`matchesPosting`) ([Posting] -> Bool) -> [Posting] -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> [Posting]
tpostings Transaction
t
matchesTransaction (Empty _) _ = Bool
True
matchesTransaction (Depth d :: Int
d) t :: Transaction
t = (Posting -> Bool) -> [Posting] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int -> Query
Depth Int
d Query -> Posting -> Bool
`matchesPosting`) ([Posting] -> Bool) -> [Posting] -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> [Posting]
tpostings Transaction
t
matchesTransaction q :: Query
q@(Sym _) t :: Transaction
t = (Posting -> Bool) -> [Posting] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query
q Query -> Posting -> Bool
`matchesPosting`) ([Posting] -> Bool) -> [Posting] -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> [Posting]
tpostings Transaction
t
matchesTransaction (Tag n :: String
n v :: Maybe String
v) t :: Transaction
t = case (String
n, Maybe String
v) of
("payee", Just v :: String
v) -> String -> String -> Bool
regexMatchesCI String
v (String -> Bool) -> (Transaction -> String) -> Transaction -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
transactionPayee (Transaction -> Bool) -> Transaction -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction
t
("note", Just v :: String
v) -> String -> String -> Bool
regexMatchesCI String
v (String -> Bool) -> (Transaction -> String) -> Transaction -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack (Text -> String) -> (Transaction -> Text) -> Transaction -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Transaction -> Text
transactionNote (Transaction -> Bool) -> Transaction -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction
t
(n :: String
n, v :: Maybe String
v) -> String -> Maybe String -> [(Text, Text)] -> Bool
matchesTags String
n Maybe String
v ([(Text, Text)] -> Bool) -> [(Text, Text)] -> Bool
forall a b. (a -> b) -> a -> b
$ Transaction -> [(Text, Text)]
transactionAllTags Transaction
t
matchesTags :: Regexp -> Maybe Regexp -> [Tag] -> Bool
matchesTags :: String -> Maybe String -> [(Text, Text)] -> Bool
matchesTags namepat :: String
namepat valuepat :: Maybe String
valuepat = Bool -> Bool
not (Bool -> Bool)
-> ([(Text, Text)] -> Bool) -> [(Text, Text)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Text, Text)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([(Text, Text)] -> Bool)
-> ([(Text, Text)] -> [(Text, Text)]) -> [(Text, Text)] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> Bool) -> [(Text, Text)] -> [(Text, Text)]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> Maybe String -> (Text, Text) -> Bool
match String
namepat Maybe String
valuepat)
where
match :: String -> Maybe String -> (Text, Text) -> Bool
match npat :: String
npat Nothing (n :: Text
n,_) = String -> String -> Bool
regexMatchesCI String
npat (Text -> String
T.unpack Text
n)
match npat :: String
npat (Just vpat :: String
vpat) (n :: Text
n,v :: Text
v) = String -> String -> Bool
regexMatchesCI String
npat (Text -> String
T.unpack Text
n) Bool -> Bool -> Bool
&& String -> String -> Bool
regexMatchesCI String
vpat (Text -> String
T.unpack Text
v)
matchesPriceDirective :: Query -> PriceDirective -> Bool
matchesPriceDirective :: Query -> PriceDirective -> Bool
matchesPriceDirective (Query
None) _ = Bool
False
matchesPriceDirective (Not q :: Query
q) p :: PriceDirective
p = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Query -> PriceDirective -> Bool
matchesPriceDirective Query
q PriceDirective
p
matchesPriceDirective (Or qs :: [Query]
qs) p :: PriceDirective
p = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Query -> PriceDirective -> Bool
`matchesPriceDirective` PriceDirective
p) [Query]
qs
matchesPriceDirective (And qs :: [Query]
qs) p :: PriceDirective
p = (Query -> Bool) -> [Query] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Query -> PriceDirective -> Bool
`matchesPriceDirective` PriceDirective
p) [Query]
qs
matchesPriceDirective q :: Query
q@(Amt _ _) p :: PriceDirective
p = Query -> Amount -> Bool
matchesAmount Query
q (PriceDirective -> Amount
pdamount PriceDirective
p)
matchesPriceDirective q :: Query
q@(Sym _) p :: PriceDirective
p = Query -> Text -> Bool
matchesCommodity Query
q (PriceDirective -> Text
pdcommodity PriceDirective
p)
matchesPriceDirective (Date span :: DateSpan
span) p :: PriceDirective
p = DateSpan -> Day -> Bool
spanContainsDate DateSpan
span (PriceDirective -> Day
pddate PriceDirective
p)
matchesPriceDirective _ _ = Bool
True
tests_Query :: TestTree
tests_Query = String -> [TestTree] -> TestTree
tests "Query" [
String -> Assertion -> TestTree
test "simplifyQuery" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
Or [String -> Query
Acct "a"]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Acct "a")
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
Or [Query
Any,Query
None]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query
Any)
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [Query
Any,Query
None]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query
None)
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [Query
Any,Query
Any]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query
Any)
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [String -> Query
Acct "b",Query
Any]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Acct "b")
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [Query
Any,[Query] -> Query
And [DateSpan -> Query
Date (Maybe Day -> Maybe Day -> DateSpan
DateSpan Maybe Day
forall a. Maybe a
Nothing Maybe Day
forall a. Maybe a
Nothing)]]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query
Any)
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [DateSpan -> Query
Date (Maybe Day -> Maybe Day -> DateSpan
DateSpan Maybe Day
forall a. Maybe a
Nothing (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2013-01-01")), DateSpan -> Query
Date (Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2012-01-01") Maybe Day
forall a. Maybe a
Nothing)])
Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (DateSpan -> Query
Date (Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2012-01-01") (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2013-01-01")))
(Query -> Query
simplifyQuery (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ [Query] -> Query
And [[Query] -> Query
Or [],[Query] -> Query
Or [String -> Query
Desc "b b"]]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Desc "b b")
,String -> Assertion -> TestTree
test "parseQuery" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
(Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "acct:'expenses:autres d\233penses' desc:b") (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ([Query] -> Query
And [String -> Query
Acct "expenses:autres d\233penses", String -> Query
Desc "b"], [])
Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "inacct:a desc:\"b b\"" (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Desc "b b", [Text -> QueryOpt
QueryOptInAcct "a"])
Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "inacct:a inacct:b" (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query
Any, [Text -> QueryOpt
QueryOptInAcct "a", Text -> QueryOpt
QueryOptInAcct "b"])
Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "desc:'x x'" (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Desc "x x", [])
Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "'a a' 'b" (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ([Query] -> Query
Or [String -> Query
Acct "a a",String -> Query
Acct "'b"], [])
Day -> Text -> (Query, [QueryOpt])
parseQuery Day
nulldate "\"" (Query, [QueryOpt]) -> (Query, [QueryOpt]) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (String -> Query
Acct "\"", [])
,String -> Assertion -> TestTree
test "words''" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
([Text] -> Text -> [Text]
words'' [] "a b") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["a","b"]
([Text] -> Text -> [Text]
words'' [] "'a b'") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["a b"]
([Text] -> Text -> [Text]
words'' [] "not:a b") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["not:a","b"]
([Text] -> Text -> [Text]
words'' [] "not:'a b'") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["not:a b"]
([Text] -> Text -> [Text]
words'' [] "'not:a b'") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["not:a b"]
([Text] -> Text -> [Text]
words'' ["desc:"] "not:desc:'a b'") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["not:desc:a b"]
([Text] -> Text -> [Text]
words'' [Text]
prefixes "\"acct:expenses:autres d\233penses\"") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["acct:expenses:autres d\233penses"]
([Text] -> Text -> [Text]
words'' [Text]
prefixes "\"") [Text] -> [Text] -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= ["\""]
,String -> Assertion -> TestTree
test "filterQuery" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
(Query -> Bool) -> Query -> Query
filterQuery Query -> Bool
queryIsDepth Query
Any Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Query
Any
(Query -> Bool) -> Query -> Query
filterQuery Query -> Bool
queryIsDepth (Int -> Query
Depth 1) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Int -> Query
Depth 1
(Query -> Bool) -> Query -> Query
filterQuery (Bool -> Bool
not(Bool -> Bool) -> (Query -> Bool) -> Query -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Query -> Bool
queryIsDepth) ([Query] -> Query
And [[Query] -> Query
And [Status -> Query
StatusQ Status
Cleared,Int -> Query
Depth 1]]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Status -> Query
StatusQ Status
Cleared
(Query -> Bool) -> Query -> Query
filterQuery Query -> Bool
queryIsDepth ([Query] -> Query
And [DateSpan -> Query
Date DateSpan
nulldatespan, Query -> Query
Not ([Query] -> Query
Or [Query
Any, Int -> Query
Depth 1])]) Query -> Query -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= Query
Any
,String -> Assertion -> TestTree
test "parseQueryTerm" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "a" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Acct "a")
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "acct:expenses:autres d\233penses" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Query
Acct "expenses:autres d\233penses")
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "not:desc:a b" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Query -> Query
Not (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ String -> Query
Desc "a b")
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "status:1" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Cleared)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "status:*" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Cleared)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "status:!" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Pending)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "status:0" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Unmarked)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "status:" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Unmarked)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "payee:x" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "payee" (String -> Maybe String
forall a. a -> Maybe a
Just "x"))
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "note:x" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "note" (String -> Maybe String
forall a. a -> Maybe a
Just "x"))
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "real:1" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Bool -> Query
Real Bool
True)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "date:2008" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date (DateSpan -> Query) -> DateSpan -> Query
forall a b. (a -> b) -> a -> b
$ Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2008/01/01") (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2009/01/01"))
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "date:from 2012/5/17" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date (DateSpan -> Query) -> DateSpan -> Query
forall a b. (a -> b) -> a -> b
$ Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2012/05/17") Maybe Day
forall a. Maybe a
Nothing)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "date:20180101-201804" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date (DateSpan -> Query) -> DateSpan -> Query
forall a b. (a -> b) -> a -> b
$ Maybe Day -> Maybe Day -> DateSpan
DateSpan (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2018/01/01") (Day -> Maybe Day
forall a. a -> Maybe a
Just (Day -> Maybe Day) -> Day -> Maybe Day
forall a b. (a -> b) -> a -> b
$ String -> Day
parsedate "2018/04/01"))
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "inacct:a" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (QueryOpt -> Either Query QueryOpt
forall a b. b -> Either a b
Right (QueryOpt -> Either Query QueryOpt)
-> QueryOpt -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ Text -> QueryOpt
QueryOptInAcct "a")
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "tag:a" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "a" Maybe String
forall a. Maybe a
Nothing)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "tag:a=some value" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ String -> Maybe String -> Query
Tag "a" (String -> Maybe String
forall a. a -> Maybe a
Just "some value"))
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "amt:<0" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ OrdPlus -> Quantity -> Query
Amt OrdPlus
Lt 0)
Day -> Text -> Either Query QueryOpt
parseQueryTerm Day
nulldate "amt:>10000.10" Either Query QueryOpt -> Either Query QueryOpt -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (Query -> Either Query QueryOpt
forall a b. a -> Either a b
Left (Query -> Either Query QueryOpt) -> Query -> Either Query QueryOpt
forall a b. (a -> b) -> a -> b
$ OrdPlus -> Quantity -> Query
Amt OrdPlus
AbsGt 10000.1)
,String -> Assertion -> TestTree
test "parseAmountQueryTerm" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm "<0" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
Lt,0)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm ">0" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
Gt,0)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm ">10000.10" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
AbsGt,10000.1)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm "=0.23" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
AbsEq,0.23)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm "0.23" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
AbsEq,0.23)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm "<=+0.23" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
LtEq,0.23)
Text -> (OrdPlus, Quantity)
parseAmountQueryTerm "-0.23" (OrdPlus, Quantity) -> (OrdPlus, Quantity) -> Assertion
forall a. (Eq a, Show a, HasCallStack) => a -> a -> Assertion
@?= (OrdPlus
Eq,(-0.23))
,String -> Assertion -> TestTree
test "matchesAccount" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Query
Acct "b:c") Query -> Text -> Bool
`matchesAccount` "a:bb:c:d"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Query
Acct "^a:b") Query -> Text -> Bool
`matchesAccount` "c:a:b"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Int -> Query
Depth 2 Query -> Text -> Bool
`matchesAccount` "a"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Int -> Query
Depth 2 Query -> Text -> Bool
`matchesAccount` "a:b"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int -> Query
Depth 2 Query -> Text -> Bool
`matchesAccount` "a:b:c"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date DateSpan
nulldatespan Query -> Text -> Bool
`matchesAccount` "a"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ DateSpan -> Query
Date2 DateSpan
nulldatespan Query -> Text -> Bool
`matchesAccount` "a"
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "a" Maybe String
forall a. Maybe a
Nothing) Query -> Text -> Bool
`matchesAccount` "a"
,String -> [TestTree] -> TestTree
tests "matchesPosting" [
String -> Assertion -> TestTree
test "positive match on cleared posting status" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (Status -> Query
StatusQ Status
Cleared) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pstatus :: Status
pstatus=Status
Cleared}
,String -> Assertion -> TestTree
test "negative match on cleared posting status" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Query -> Query
Not (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Cleared) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pstatus :: Status
pstatus=Status
Cleared}
,String -> Assertion -> TestTree
test "positive match on unmarked posting status" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (Status -> Query
StatusQ Status
Unmarked) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pstatus :: Status
pstatus=Status
Unmarked}
,String -> Assertion -> TestTree
test "negative match on unmarked posting status" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Query -> Query
Not (Query -> Query) -> Query -> Query
forall a b. (a -> b) -> a -> b
$ Status -> Query
StatusQ Status
Unmarked) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pstatus :: Status
pstatus=Status
Unmarked}
,String -> Assertion -> TestTree
test "positive match on true posting status acquired from transaction" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (Status -> Query
StatusQ Status
Cleared) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pstatus :: Status
pstatus=Status
Unmarked,ptransaction :: Maybe Transaction
ptransaction=Transaction -> Maybe Transaction
forall a. a -> Maybe a
Just Transaction
nulltransaction{tstatus :: Status
tstatus=Status
Cleared}}
,String -> Assertion -> TestTree
test "real:1 on real posting" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (Bool -> Query
Real Bool
True) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptype :: PostingType
ptype=PostingType
RegularPosting}
,String -> Assertion -> TestTree
test "real:1 on virtual posting fails" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Bool -> Query
Real Bool
True) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptype :: PostingType
ptype=PostingType
VirtualPosting}
,String -> Assertion -> TestTree
test "real:1 on balanced virtual posting fails" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (Bool -> Query
Real Bool
True) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptype :: PostingType
ptype=PostingType
BalancedVirtualPosting}
,String -> Assertion -> TestTree
test "acct:" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Query
Acct "'b") Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{paccount :: Text
paccount="'b"}
,String -> Assertion -> TestTree
test "tag:" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "a" (String -> Maybe String
forall a. a -> Maybe a
Just "r$")) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo" Maybe String
forall a. Maybe a
Nothing) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo","")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo" Maybe String
forall a. Maybe a
Nothing) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo","baz")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo" (String -> Maybe String
forall a. a -> Maybe a
Just "a")) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo","bar")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo" (String -> Maybe String
forall a. a -> Maybe a
Just "a$")) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo","bar")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag " foo " (String -> Maybe String
forall a. a -> Maybe a
Just "a")) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo","bar")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo foo" (String -> Maybe String
forall a. a -> Maybe a
Just " ar ba ")) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("foo foo","bar bar")]}
,String -> Assertion -> TestTree
test "a tag match on a posting also sees inherited tags" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "txntag" Maybe String
forall a. Maybe a
Nothing) Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{ptransaction :: Maybe Transaction
ptransaction=Transaction -> Maybe Transaction
forall a. a -> Maybe a
Just Transaction
nulltransaction{ttags :: [(Text, Text)]
ttags=[("txntag","")]}}
,String -> Assertion -> TestTree
test "cur:" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Query
Sym "$") Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pamount :: MixedAmount
pamount=[Amount] -> MixedAmount
Mixed [Quantity -> Amount
usd 1]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Query
Sym "\\$") Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pamount :: MixedAmount
pamount=[Amount] -> MixedAmount
Mixed [Quantity -> Amount
usd 1]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Query
Sym "shekels") Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pamount :: MixedAmount
pamount=[Amount] -> MixedAmount
Mixed [Amount
nullamt{acommodity :: Text
acommodity="shekels"}]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Query
Sym "shek") Query -> Posting -> Bool
`matchesPosting` Posting
nullposting{pamount :: MixedAmount
pamount=[Amount] -> MixedAmount
Mixed [Amount
nullamt{acommodity :: Text
acommodity="shekels"}]}
]
,String -> Assertion -> TestTree
test "matchesTransaction" (Assertion -> TestTree) -> Assertion -> TestTree
forall a b. (a -> b) -> a -> b
$ do
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Query
Any Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (String -> Query
Desc "x x") Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{tdescription :: Text
tdescription="x"}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Query
Desc "x x") Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{tdescription :: Text
tdescription="x x"}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "foo" (String -> Maybe String
forall a. a -> Maybe a
Just "a")) Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{ttags :: [(Text, Text)]
ttags=[("foo","bar")]}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "payee" (String -> Maybe String
forall a. a -> Maybe a
Just "payee")) Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{tdescription :: Text
tdescription="payee|note"}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "note" (String -> Maybe String
forall a. a -> Maybe a
Just "note")) Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{tdescription :: Text
tdescription="payee|note"}
HasCallStack => String -> Bool -> Assertion
String -> Bool -> Assertion
assertBool "" (Bool -> Assertion) -> Bool -> Assertion
forall a b. (a -> b) -> a -> b
$ (String -> Maybe String -> Query
Tag "postingtag" Maybe String
forall a. Maybe a
Nothing) Query -> Transaction -> Bool
`matchesTransaction` Transaction
nulltransaction{tpostings :: [Posting]
tpostings=[Posting
nullposting{ptags :: [(Text, Text)]
ptags=[("postingtag","")]}]}
]