penny-lib-0.4.0.0: Penny/Cabin/Posts/Meta.hs
module Penny.Cabin.Posts.Meta (
M.VisibleNum(M.unVisibleNum)
, PostMeta(filteredNum, sortedNum, visibleNum, balance)
, Box
, toBoxList
) 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.Cabin.Meta as M
import qualified Penny.Cabin.Options as CO
-- | The Box type that is used throughout the Posts modules.
type Box = L.Box PostMeta
data PostMeta =
PostMeta { filteredNum :: Ly.FilteredNum
, sortedNum :: Ly.SortedNum
, visibleNum :: M.VisibleNum
, balance :: Maybe L.Balance }
deriving Show
addMetadata ::
[(L.Box (Ly.LibertyMeta, Maybe L.Balance))]
-> [Box]
addMetadata = M.visibleNums f where
f vn (lm, mb) =
PostMeta (Ly.filteredNum lm) (Ly.sortedNum lm) vn mb
-- | Adds appropriate metadata, including the running balance, to a
-- list of Box. Because all posts are incorporated into the running
-- balance, first calculates the running balance for all posts. Then,
-- removes posts we're not interested in by applying the predicate and
-- the post-filter. Finally, adds on the metadata, which will include
-- the VisibleNum.
toBoxList ::
CO.ShowZeroBalances
-> (L.Box Ly.LibertyMeta -> Bool)
-- ^ Removes posts from the report if applying this function to the
-- post returns False. Posts removed still affect the running
-- balance.
-> [Ly.PostFilterFn]
-- ^ Applies these post-filters to the list of posts that results
-- from applying the predicate above. Might remove more
-- postings. Postings removed still affect the running balance.
-> [L.Box Ly.LibertyMeta]
-> [Box]
toBoxList szb pdct pff =
addMetadata
. Ly.processPostFilters pff
. filter (pdct . fmap fst)
. addBalances szb
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')