-- | This module provides the type for the 'Priority' of a task.
module Taskwarrior.Priority
  ( parseMay
  , Priority(..)
  )
where

import qualified Data.Aeson                    as Aeson
import           Data.Aeson.Types               ( Parser )


-- | A 'Taskwarrior.Task.Task' can have the priorities 'High', 'Medium', 'Low' or none, which is modeled via a 'Maybe' 'Priority'.
data Priority = High | Medium | Low
        deriving (Priority -> Priority -> Bool
(Priority -> Priority -> Bool)
-> (Priority -> Priority -> Bool) -> Eq Priority
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Priority -> Priority -> Bool
$c/= :: Priority -> Priority -> Bool
== :: Priority -> Priority -> Bool
$c== :: Priority -> Priority -> Bool
Eq, Int -> Priority -> ShowS
[Priority] -> ShowS
Priority -> String
(Int -> Priority -> ShowS)
-> (Priority -> String) -> ([Priority] -> ShowS) -> Show Priority
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Priority] -> ShowS
$cshowList :: [Priority] -> ShowS
show :: Priority -> String
$cshow :: Priority -> String
showsPrec :: Int -> Priority -> ShowS
$cshowsPrec :: Int -> Priority -> ShowS
Show, ReadPrec [Priority]
ReadPrec Priority
Int -> ReadS Priority
ReadS [Priority]
(Int -> ReadS Priority)
-> ReadS [Priority]
-> ReadPrec Priority
-> ReadPrec [Priority]
-> Read Priority
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Priority]
$creadListPrec :: ReadPrec [Priority]
readPrec :: ReadPrec Priority
$creadPrec :: ReadPrec Priority
readList :: ReadS [Priority]
$creadList :: ReadS [Priority]
readsPrec :: Int -> ReadS Priority
$creadsPrec :: Int -> ReadS Priority
Read, Int -> Priority
Priority -> Int
Priority -> [Priority]
Priority -> Priority
Priority -> Priority -> [Priority]
Priority -> Priority -> Priority -> [Priority]
(Priority -> Priority)
-> (Priority -> Priority)
-> (Int -> Priority)
-> (Priority -> Int)
-> (Priority -> [Priority])
-> (Priority -> Priority -> [Priority])
-> (Priority -> Priority -> [Priority])
-> (Priority -> Priority -> Priority -> [Priority])
-> Enum Priority
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Priority -> Priority -> Priority -> [Priority]
$cenumFromThenTo :: Priority -> Priority -> Priority -> [Priority]
enumFromTo :: Priority -> Priority -> [Priority]
$cenumFromTo :: Priority -> Priority -> [Priority]
enumFromThen :: Priority -> Priority -> [Priority]
$cenumFromThen :: Priority -> Priority -> [Priority]
enumFrom :: Priority -> [Priority]
$cenumFrom :: Priority -> [Priority]
fromEnum :: Priority -> Int
$cfromEnum :: Priority -> Int
toEnum :: Int -> Priority
$ctoEnum :: Int -> Priority
pred :: Priority -> Priority
$cpred :: Priority -> Priority
succ :: Priority -> Priority
$csucc :: Priority -> Priority
Enum, Eq Priority
Eq Priority
-> (Priority -> Priority -> Ordering)
-> (Priority -> Priority -> Bool)
-> (Priority -> Priority -> Bool)
-> (Priority -> Priority -> Bool)
-> (Priority -> Priority -> Bool)
-> (Priority -> Priority -> Priority)
-> (Priority -> Priority -> Priority)
-> Ord Priority
Priority -> Priority -> Bool
Priority -> Priority -> Ordering
Priority -> Priority -> Priority
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Priority -> Priority -> Priority
$cmin :: Priority -> Priority -> Priority
max :: Priority -> Priority -> Priority
$cmax :: Priority -> Priority -> Priority
>= :: Priority -> Priority -> Bool
$c>= :: Priority -> Priority -> Bool
> :: Priority -> Priority -> Bool
$c> :: Priority -> Priority -> Bool
<= :: Priority -> Priority -> Bool
$c<= :: Priority -> Priority -> Bool
< :: Priority -> Priority -> Bool
$c< :: Priority -> Priority -> Bool
compare :: Priority -> Priority -> Ordering
$ccompare :: Priority -> Priority -> Ordering
$cp1Ord :: Eq Priority
Ord, Priority
Priority -> Priority -> Bounded Priority
forall a. a -> a -> Bounded a
maxBound :: Priority
$cmaxBound :: Priority
minBound :: Priority
$cminBound :: Priority
Bounded)

instance Aeson.ToJSON Priority where
  toJSON :: Priority -> Value
toJSON = \case
    Priority
High   -> Value
"H"
    Priority
Medium -> Value
"M"
    Priority
Low    -> Value
"L"

-- | Parses a JSON string to a 'Maybe' 'Priority', fails on anything else.
parseMay :: Aeson.Value -> Parser (Maybe Priority)
parseMay :: Value -> Parser (Maybe Priority)
parseMay = String
-> (Text -> Parser (Maybe Priority))
-> Value
-> Parser (Maybe Priority)
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"Priority" ((Text -> Parser (Maybe Priority))
 -> Value -> Parser (Maybe Priority))
-> (Text -> Parser (Maybe Priority))
-> Value
-> Parser (Maybe Priority)
forall a b. (a -> b) -> a -> b
$ \case
  Text
"H" -> Maybe Priority -> Parser (Maybe Priority)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Priority -> Parser (Maybe Priority))
-> Maybe Priority -> Parser (Maybe Priority)
forall a b. (a -> b) -> a -> b
$ Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
High
  Text
"M" -> Maybe Priority -> Parser (Maybe Priority)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Priority -> Parser (Maybe Priority))
-> Maybe Priority -> Parser (Maybe Priority)
forall a b. (a -> b) -> a -> b
$ Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
Medium
  Text
"L" -> Maybe Priority -> Parser (Maybe Priority)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Priority -> Parser (Maybe Priority))
-> Maybe Priority -> Parser (Maybe Priority)
forall a b. (a -> b) -> a -> b
$ Priority -> Maybe Priority
forall a. a -> Maybe a
Just Priority
Low
  Text
""  -> Maybe Priority -> Parser (Maybe Priority)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Priority
forall a. Maybe a
Nothing
  Text
s ->
    String -> Parser (Maybe Priority)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
      (String -> Parser (Maybe Priority))
-> String -> Parser (Maybe Priority)
forall a b. (a -> b) -> a -> b
$  String
"parsing Priority failed, unexpected "
      String -> ShowS
forall a. [a] -> [a] -> [a]
++ Text -> String
forall a. Show a => a -> String
show Text
s
      String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" (expected \"H\", \"M\", \"L\", or \"\")"

instance Aeson.FromJSON Priority where
  parseJSON :: Value -> Parser Priority
parseJSON Value
val = Value -> Parser (Maybe Priority)
parseMay Value
val Parser (Maybe Priority)
-> (Maybe Priority -> Parser Priority) -> Parser Priority
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Maybe Priority
Nothing ->
      String -> Parser Priority
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
        String
"parsing Priority failed, unexpected null (expected \"H\", \"M\", or \"L\")"
    Just Priority
p -> Priority -> Parser Priority
forall (f :: * -> *) a. Applicative f => a -> f a
pure Priority
p