module Mensam.API.Update where

import Data.Aeson qualified as A
import Data.Kind
import GHC.Generics

type Updatable :: Type -> Type
data Updatable a
  = Preserve
  | Overwrite a
  deriving stock (Updatable a -> Updatable a -> Bool
(Updatable a -> Updatable a -> Bool)
-> (Updatable a -> Updatable a -> Bool) -> Eq (Updatable a)
forall a. Eq a => Updatable a -> Updatable a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Updatable a -> Updatable a -> Bool
== :: Updatable a -> Updatable a -> Bool
$c/= :: forall a. Eq a => Updatable a -> Updatable a -> Bool
/= :: Updatable a -> Updatable a -> Bool
Eq, (forall x. Updatable a -> Rep (Updatable a) x)
-> (forall x. Rep (Updatable a) x -> Updatable a)
-> Generic (Updatable a)
forall x. Rep (Updatable a) x -> Updatable a
forall x. Updatable a -> Rep (Updatable a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Updatable a) x -> Updatable a
forall a x. Updatable a -> Rep (Updatable a) x
$cfrom :: forall a x. Updatable a -> Rep (Updatable a) x
from :: forall x. Updatable a -> Rep (Updatable a) x
$cto :: forall a x. Rep (Updatable a) x -> Updatable a
to :: forall x. Rep (Updatable a) x -> Updatable a
Generic, Eq (Updatable a)
Eq (Updatable a) =>
(Updatable a -> Updatable a -> Ordering)
-> (Updatable a -> Updatable a -> Bool)
-> (Updatable a -> Updatable a -> Bool)
-> (Updatable a -> Updatable a -> Bool)
-> (Updatable a -> Updatable a -> Bool)
-> (Updatable a -> Updatable a -> Updatable a)
-> (Updatable a -> Updatable a -> Updatable a)
-> Ord (Updatable a)
Updatable a -> Updatable a -> Bool
Updatable a -> Updatable a -> Ordering
Updatable a -> Updatable a -> Updatable a
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
forall a. Ord a => Eq (Updatable a)
forall a. Ord a => Updatable a -> Updatable a -> Bool
forall a. Ord a => Updatable a -> Updatable a -> Ordering
forall a. Ord a => Updatable a -> Updatable a -> Updatable a
$ccompare :: forall a. Ord a => Updatable a -> Updatable a -> Ordering
compare :: Updatable a -> Updatable a -> Ordering
$c< :: forall a. Ord a => Updatable a -> Updatable a -> Bool
< :: Updatable a -> Updatable a -> Bool
$c<= :: forall a. Ord a => Updatable a -> Updatable a -> Bool
<= :: Updatable a -> Updatable a -> Bool
$c> :: forall a. Ord a => Updatable a -> Updatable a -> Bool
> :: Updatable a -> Updatable a -> Bool
$c>= :: forall a. Ord a => Updatable a -> Updatable a -> Bool
>= :: Updatable a -> Updatable a -> Bool
$cmax :: forall a. Ord a => Updatable a -> Updatable a -> Updatable a
max :: Updatable a -> Updatable a -> Updatable a
$cmin :: forall a. Ord a => Updatable a -> Updatable a -> Updatable a
min :: Updatable a -> Updatable a -> Updatable a
Ord, ReadPrec [Updatable a]
ReadPrec (Updatable a)
Int -> ReadS (Updatable a)
ReadS [Updatable a]
(Int -> ReadS (Updatable a))
-> ReadS [Updatable a]
-> ReadPrec (Updatable a)
-> ReadPrec [Updatable a]
-> Read (Updatable a)
forall a. Read a => ReadPrec [Updatable a]
forall a. Read a => ReadPrec (Updatable a)
forall a. Read a => Int -> ReadS (Updatable a)
forall a. Read a => ReadS [Updatable a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Updatable a)
readsPrec :: Int -> ReadS (Updatable a)
$creadList :: forall a. Read a => ReadS [Updatable a]
readList :: ReadS [Updatable a]
$creadPrec :: forall a. Read a => ReadPrec (Updatable a)
readPrec :: ReadPrec (Updatable a)
$creadListPrec :: forall a. Read a => ReadPrec [Updatable a]
readListPrec :: ReadPrec [Updatable a]
Read, Int -> Updatable a -> ShowS
[Updatable a] -> ShowS
Updatable a -> String
(Int -> Updatable a -> ShowS)
-> (Updatable a -> String)
-> ([Updatable a] -> ShowS)
-> Show (Updatable a)
forall a. Show a => Int -> Updatable a -> ShowS
forall a. Show a => [Updatable a] -> ShowS
forall a. Show a => Updatable a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Updatable a -> ShowS
showsPrec :: Int -> Updatable a -> ShowS
$cshow :: forall a. Show a => Updatable a -> String
show :: Updatable a -> String
$cshowList :: forall a. Show a => [Updatable a] -> ShowS
showList :: [Updatable a] -> ShowS
Show)

instance A.FromJSON a => A.FromJSON (Updatable a) where
  parseJSON :: Value -> Parser (Updatable a)
parseJSON = String
-> (Object -> Parser (Updatable a))
-> Value
-> Parser (Updatable a)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
A.withObject String
"Updatable" ((Object -> Parser (Updatable a)) -> Value -> Parser (Updatable a))
-> (Object -> Parser (Updatable a))
-> Value
-> Parser (Updatable a)
forall a b. (a -> b) -> a -> b
$ \Object
v -> do
    Bool
isUpdate :: Bool <- Object
v Object -> Key -> Parser Bool
forall a. FromJSON a => Object -> Key -> Parser a
A..: Key
"update"
    if Bool
isUpdate
      then do
        a
value :: a <- Object
v Object -> Key -> Parser a
forall a. FromJSON a => Object -> Key -> Parser a
A..: Key
"value"
        Updatable a -> Parser (Updatable a)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Updatable a -> Parser (Updatable a))
-> Updatable a -> Parser (Updatable a)
forall a b. (a -> b) -> a -> b
$ a -> Updatable a
forall a. a -> Updatable a
Overwrite a
value
      else do
        Maybe Value
value :: Maybe A.Value <- Object
v Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
A..:! Key
"value"
        case Maybe Value
value of
          Maybe Value
Nothing -> Updatable a -> Parser (Updatable a)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Updatable a
forall a. Updatable a
Preserve
          Just Value
_ -> String -> Parser (Updatable a)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Expected no value to be present, because the 'update' field is false."

instance A.ToJSON a => A.ToJSON (Updatable a) where
  toJSON :: Updatable a -> Value
toJSON = \case
    Updatable a
Preserve ->
      [Pair] -> Value
A.object
        [ (Key
"update", Bool -> Value
A.Bool Bool
False)
        ]
    Overwrite a
value ->
      [Pair] -> Value
A.object
        [ (Key
"update", Bool -> Value
A.Bool Bool
True)
        , (Key
"value", a -> Value
forall a. ToJSON a => a -> Value
A.toJSON a
value)
        ]