lib: clarify filterQuery, add filterQueryOrNotQuery (#1783)

This commit is contained in:
Simon Michael 2021-12-09 12:57:26 -10:00
parent 46cc60779d
commit 25598a231f

View File

@ -23,6 +23,7 @@ module Hledger.Query (
parseQueryTerm, parseQueryTerm,
simplifyQuery, simplifyQuery,
filterQuery, filterQuery,
filterQueryOrNotQuery,
-- * accessors -- * accessors
queryIsNull, queryIsNull,
queryIsAcct, queryIsAcct,
@ -378,16 +379,30 @@ simplifyQuery q =
same [] = True same [] = True
same (a:as) = all (a==) as same (a:as) = all (a==) as
-- | Remove query terms (or whole sub-expressions) not matching the given -- | Remove query terms (or whole sub-expressions) from this query
-- predicate from this query. XXX Semantics not completely clear. -- which do not match the given predicate.
-- XXX Semantics not completely clear.
filterQuery :: (Query -> Bool) -> Query -> Query filterQuery :: (Query -> Bool) -> Query -> Query
filterQuery p = simplifyQuery . filterQuery' p filterQuery p = simplifyQuery . filterQuery' p
where
filterQuery' :: (Query -> Bool) -> Query -> Query
filterQuery' p (And qs) = And $ map (filterQuery p) qs
filterQuery' p (Or qs) = Or $ map (filterQuery p) qs
filterQuery' p q = if p q then q else Any
filterQuery' :: (Query -> Bool) -> Query -> Query -- | Remove query terms (or whole sub-expressions) from this query
filterQuery' p (And qs) = And $ map (filterQuery p) qs -- which match neither the given predicate nor that predicate negated
filterQuery' p (Or qs) = Or $ map (filterQuery p) qs -- (eg, if predicate is queryIsAcct, this will keep both "acct:" and "not:acct:" terms).
-- filterQuery' p (Not q) = Not $ filterQuery p q -- (Since 1.24.1, might be merged into filterQuery in future.)
filterQuery' p q = if p q then q else Any -- XXX Semantics not completely clear.
filterQueryOrNotQuery :: (Query -> Bool) -> Query -> Query
filterQueryOrNotQuery p = simplifyQuery . filterQuery' p
where
filterQuery' :: (Query -> Bool) -> Query -> Query
filterQuery' p (And qs) = And $ map (filterQuery p) qs
filterQuery' p (Or qs) = Or $ map (filterQuery p) qs
filterQuery' p (Not q) | p q = Not $ filterQuery p q
filterQuery' p q = if p q then q else Any
-- * accessors -- * accessors
@ -398,6 +413,9 @@ queryIsNull (And []) = True
queryIsNull (Not (Or [])) = True queryIsNull (Not (Or [])) = True
queryIsNull _ = False queryIsNull _ = False
-- | Is this a simple query of this type ("depth:D") ?
-- Note, does not match a compound query like "not:depth:D" or "depth:D acct:A".
-- Likewise for the following functions.
queryIsDepth :: Query -> Bool queryIsDepth :: Query -> Bool
queryIsDepth (Depth _) = True queryIsDepth (Depth _) = True
queryIsDepth _ = False queryIsDepth _ = False