module Penny.Cabin.Posts.Meta ( M.VisibleNum(M.unVisibleNum) , PostMeta(filteredNum, sortedNum, visibleNum, balance) , filterBoxes , addMetadata ) where import Data.List (mapAccumL) import qualified Penny.Lincoln as L import qualified Penny.Lincoln.Queries as Q import qualified Penny.Liberty as Ly import qualified Penny.Liberty.Expressions as Exp import qualified Penny.Cabin.Meta as M import qualified Penny.Cabin.Options as CO data PostMeta = PostMeta { filteredNum :: Ly.FilteredNum , sortedNum :: Ly.SortedNum , visibleNum :: M.VisibleNum , balance :: Maybe L.Balance } deriving Show -- | Takes a list of Box with LibertyMeta, and a list of tokens from -- the command line, and a list of post filters. Filters the list of -- Box and processes the post filter. Fails if the expression fails to -- produce a result. filterBoxes :: [Exp.Token (L.Box Ly.LibertyMeta -> Bool)] -> [Ly.PostFilterFn] -> [L.Box Ly.LibertyMeta] -> Maybe [L.Box Ly.LibertyMeta] filterBoxes tks pfs bs = fmap fltr (Ly.parsePredicate tks) where fltr p = Ly.processPostFilters pfs . filter p $ bs -- | Applied to a list of Box that have already been filtered, returns -- a list of Box with posting metadata. addMetadata :: CO.ShowZeroBalances -> [L.Box Ly.LibertyMeta] -> [L.Box PostMeta] addMetadata szb = M.visibleNums f . addBalances szb where f vn (lm, mb) = PostMeta (Ly.filteredNum lm) (Ly.sortedNum lm) vn mb addBalances :: CO.ShowZeroBalances -> [L.Box Ly.LibertyMeta] -> [(L.Box (Ly.LibertyMeta, Maybe L.Balance))] addBalances szb = snd . mapAccumL (balanceAccum szb) Nothing balanceAccum :: CO.ShowZeroBalances -> Maybe L.Balance -> L.Box Ly.LibertyMeta -> (Maybe L.Balance, (L.Box (Ly.LibertyMeta, Maybe L.Balance))) balanceAccum (CO.ShowZeroBalances szb) mb po = let balThis = L.entryToBalance . Q.entry . L.boxPostFam $ po balNew = case mb of Nothing -> balThis Just balOld -> L.addBalances balOld balThis balNoZeroes = L.removeZeroCommodities balNew bal' = if szb then Just balNew else balNoZeroes po' = L.Box (L.boxMeta po, bal') (L.boxPostFam po) in (bal', po')