diff options
Diffstat (limited to 'app/Issue/Filter.hs')
-rw-r--r-- | app/Issue/Filter.hs | 39 |
1 files changed, 25 insertions, 14 deletions
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 |