-- | Provides the 'Annotation' type with 'Data.Aeson.ToJSON' and 'Data.Aeson.FromJSON' instances.
module Taskwarrior.Annotation
  ( Annotation(..)
  )
where

import qualified Taskwarrior.Time              as Time
import           Data.Time                      ( UTCTime )
import           Data.Text                      ( Text )
import           Data.Aeson                     ( (.:)
                                                , (.=)
                                                )
import qualified Data.Aeson                    as Aeson

-- | A taskwarrior 'Taskwarrior.Task.Task' can have multiple annotations. They contain a timestamp 'entry' and a 'description'.
data Annotation = Annotation { Annotation -> UTCTime
entry :: UTCTime, Annotation -> Text
description :: Text } deriving (Annotation -> Annotation -> Bool
(Annotation -> Annotation -> Bool)
-> (Annotation -> Annotation -> Bool) -> Eq Annotation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Annotation -> Annotation -> Bool
$c/= :: Annotation -> Annotation -> Bool
== :: Annotation -> Annotation -> Bool
$c== :: Annotation -> Annotation -> Bool
Eq, Int -> Annotation -> ShowS
[Annotation] -> ShowS
Annotation -> String
(Int -> Annotation -> ShowS)
-> (Annotation -> String)
-> ([Annotation] -> ShowS)
-> Show Annotation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Annotation] -> ShowS
$cshowList :: [Annotation] -> ShowS
show :: Annotation -> String
$cshow :: Annotation -> String
showsPrec :: Int -> Annotation -> ShowS
$cshowsPrec :: Int -> Annotation -> ShowS
Show, ReadPrec [Annotation]
ReadPrec Annotation
Int -> ReadS Annotation
ReadS [Annotation]
(Int -> ReadS Annotation)
-> ReadS [Annotation]
-> ReadPrec Annotation
-> ReadPrec [Annotation]
-> Read Annotation
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Annotation]
$creadListPrec :: ReadPrec [Annotation]
readPrec :: ReadPrec Annotation
$creadPrec :: ReadPrec Annotation
readList :: ReadS [Annotation]
$creadList :: ReadS [Annotation]
readsPrec :: Int -> ReadS Annotation
$creadsPrec :: Int -> ReadS Annotation
Read, Eq Annotation
Eq Annotation
-> (Annotation -> Annotation -> Ordering)
-> (Annotation -> Annotation -> Bool)
-> (Annotation -> Annotation -> Bool)
-> (Annotation -> Annotation -> Bool)
-> (Annotation -> Annotation -> Bool)
-> (Annotation -> Annotation -> Annotation)
-> (Annotation -> Annotation -> Annotation)
-> Ord Annotation
Annotation -> Annotation -> Bool
Annotation -> Annotation -> Ordering
Annotation -> Annotation -> Annotation
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 :: Annotation -> Annotation -> Annotation
$cmin :: Annotation -> Annotation -> Annotation
max :: Annotation -> Annotation -> Annotation
$cmax :: Annotation -> Annotation -> Annotation
>= :: Annotation -> Annotation -> Bool
$c>= :: Annotation -> Annotation -> Bool
> :: Annotation -> Annotation -> Bool
$c> :: Annotation -> Annotation -> Bool
<= :: Annotation -> Annotation -> Bool
$c<= :: Annotation -> Annotation -> Bool
< :: Annotation -> Annotation -> Bool
$c< :: Annotation -> Annotation -> Bool
compare :: Annotation -> Annotation -> Ordering
$ccompare :: Annotation -> Annotation -> Ordering
$cp1Ord :: Eq Annotation
Ord)

instance Aeson.FromJSON Annotation where
  parseJSON :: Value -> Parser Annotation
parseJSON = String
-> (Object -> Parser Annotation) -> Value -> Parser Annotation
forall a. String -> (Object -> Parser a) -> Value -> Parser a
Aeson.withObject String
"Annotation" ((Object -> Parser Annotation) -> Value -> Parser Annotation)
-> (Object -> Parser Annotation) -> Value -> Parser Annotation
forall a b. (a -> b) -> a -> b
$ \Object
o -> do
    Text
description <- Object
o Object -> Text -> Parser Text
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"description"
    UTCTime
entry       <- Object
o Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
"entry" Parser Value -> (Value -> Parser UTCTime) -> Parser UTCTime
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Value -> Parser UTCTime
Time.parse
    Annotation -> Parser Annotation
forall (f :: * -> *) a. Applicative f => a -> f a
pure Annotation :: UTCTime -> Text -> Annotation
Annotation { Text
UTCTime
entry :: UTCTime
description :: Text
description :: Text
entry :: UTCTime
.. }

instance Aeson.ToJSON Annotation where
  toJSON :: Annotation -> Value
toJSON Annotation {Text
UTCTime
description :: Text
entry :: UTCTime
description :: Annotation -> Text
entry :: Annotation -> UTCTime
..} =
    [Pair] -> Value
Aeson.object [Text
"description" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
description, Text
"entry" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= UTCTime -> Value
Time.toValue UTCTime
entry]