diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/History.hs | 4 | ||||
-rw-r--r-- | app/Issue/Filter.hs | 39 |
2 files changed, 27 insertions, 16 deletions
diff --git a/app/History.hs b/app/History.hs index 4f62610..d2e6a46 100644 --- a/app/History.hs +++ b/app/History.hs @@ -12,7 +12,7 @@ import Data.Text.Encoding (decodeUtf8) import GHC.Generics (Generic) import Git qualified import Issue (Issue (..), fromMatch, id) -import Issue.Filter (Filter, applyFilter) +import Issue.Filter (Filter, applyFilters) import Issue.Sort (Sort, applySort) import Issue.Tag qualified as I import Parallel (parMapM) @@ -54,7 +54,7 @@ listIssues sort filters paths = do commitInfoWorkingTree <- getCommitInfoWorkingTree paths let eventses = getEvents hashFirst issuesInitial (commitInfos ++ [commitInfoWorkingTree]) let issues = mapMaybe issueFromIssueEvents eventses - issuesFiltered = filter (applyFilter filters) issues + issuesFiltered = applyFilters filters issues issuesSorted = applySort sort issuesFiltered issuesWithinPaths = case paths of diff --git a/app/Issue/Filter.hs b/app/Issue/Filter.hs index 90b75de..c330407 100644 --- a/app/Issue/Filter.hs +++ b/app/Issue/Filter.hs @@ -1,10 +1,11 @@ module Issue.Filter ( Filter, filterArg, - applyFilter, + applyFilters, ) where +import Control.Applicative (liftA2) import Control.Arrow (second) import Data.Text (Text) import Data.Text qualified as T @@ -12,9 +13,12 @@ import Issue (Issue (..)) import Issue.Tag (Tag (..)) import Options.Applicative qualified as O -data Filter - = ExcludeByTag Text (Maybe Text) - | IncludeByTag Text (Maybe Text) +data Filter = Filter Mode SimpleFilter deriving (Show) + +data Mode = Include | Exclude deriving (Show) + +data SimpleFilter + = ByTag Text (Maybe Text) deriving (Show) filterArg :: O.Parser [Filter] @@ -31,9 +35,9 @@ filterArg = where parse s | "@" `T.isPrefixOf` s = - Just (uncurry IncludeByTag (splitValue (T.drop 1 s))) + Just (Filter Include (uncurry ByTag (splitValue (T.drop 1 s)))) | "!@" `T.isPrefixOf` s = - Just (uncurry ExcludeByTag (splitValue (T.drop 2 s))) + Just (Filter Exclude (uncurry ByTag (splitValue (T.drop 2 s)))) | otherwise = Nothing splitValue :: Text -> (Text, Maybe Text) @@ -41,15 +45,22 @@ filterArg = (k, "") -> (k, Nothing) (k, v) -> (k, Just v) -applyFilter :: [Filter] -> Issue -> Bool -applyFilter [] _ = True -applyFilter (IncludeByTag k v : fs) i = - applyByTag k v i && applyFilter fs i -applyFilter (ExcludeByTag k v : fs) i = - not (applyByTag k v i) && applyFilter fs i +applyFilters :: [Filter] -> ([Issue] -> [Issue]) +applyFilters fs = filter (filtersPredicate fs) + +filtersPredicate :: [Filter] -> (Issue -> Bool) +filtersPredicate [] = \_ -> True +filtersPredicate fs = foldr1 (liftA2 (&&)) (map filterPredicate fs) + +filterPredicate :: Filter -> (Issue -> Bool) +filterPredicate (Filter m sf) = modePredicate m (simpleFilterPredicate sf) + +modePredicate :: Mode -> (Issue -> Bool) -> (Issue -> Bool) +modePredicate Include p = p +modePredicate Exclude p = not . p -applyByTag :: Text -> Maybe Text -> Issue -> Bool -applyByTag k v i = any ((&&) <$> matchKey <*> matchValue) i.tags +simpleFilterPredicate :: SimpleFilter -> (Issue -> Bool) +simpleFilterPredicate (ByTag k v) i = any ((&&) <$> matchKey <*> matchValue) i.tags where matchKey (Tag k' _) = k' == k matchValue (Tag _ v') = maybe True ((==) v') v |