aboutsummaryrefslogtreecommitdiffstats
path: root/app/Issue
diff options
context:
space:
mode:
Diffstat (limited to 'app/Issue')
-rw-r--r--app/Issue/Sort.hs68
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)
+ )