diff options
Diffstat (limited to 'app/Issue/Sort.hs')
-rw-r--r-- | app/Issue/Sort.hs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/app/Issue/Sort.hs b/app/Issue/Sort.hs new file mode 100644 index 0000000..1a0b3ff --- /dev/null +++ b/app/Issue/Sort.hs @@ -0,0 +1,68 @@ +module Issue.Sort + ( Sort, + Order, + SortBy, + applySort, + sortArg, + ) +where + +import Data.List (sort, sortBy) +import Data.Maybe (mapMaybe) +import Data.Ord (comparing) +import Data.Text (Text) +import Data.Text qualified as T +import Issue (Issue (..)) +import Issue.Tag (Tag (..)) +import Options.Applicative qualified as O + +data Sort = Sort Order SortBy + deriving (Show) + +data Order + = Asc + | Desc + deriving (Show, Eq) + +data SortBy + = SortByTag Text + deriving (Show) + +defaultSort :: Sort +defaultSort = Sort Asc (SortByTag "@createdAt") + +sortArg :: O.Parser [Sort] +sortArg = + O.many + ( O.option + (O.maybeReader (parse . T.pack)) + ( O.long "sort" + <> O.short 's' + <> O.metavar "SORT" + <> O.help "Sort selected issues. (Defaults: `-@createdAt`)" + ) + ) + where + parse s + | "@" `T.isPrefixOf` s = Just (Sort Asc (SortByTag (T.drop 1 s))) + | "-@" `T.isPrefixOf` s = Just (Sort Desc (SortByTag (T.drop 2 s))) + | otherwise = Nothing + +applySort :: [Sort] -> [Issue] -> [Issue] +applySort cs = compose (defaultSort : cs) + where + compose :: [Sort] -> ([Issue] -> [Issue]) + compose = foldr (.) id . map toSort + + toSort :: Sort -> ([Issue] -> [Issue]) + toSort (Sort order sortBy') = + (if order == Desc then reverse else id) + . sortBy (comparing (applySortBy sortBy')) + +applySortBy :: SortBy -> Issue -> [Text] +applySortBy (SortByTag k) i = + sort + ( mapMaybe + (\(Tag k' v) -> if k' == k then Just v else Nothing) + (i.tags ++ i.internalTags) + ) |