-- | Implements
module HomeAssistant.Common.Notify (
    NotificationData(..),
    Notification,
    notification,
    setNotificationTitle,
    setNotificationData,
    notify
) where

--------------------------------------------------------------------------------

import Data.Aeson
import qualified Data.Text as T

import Deriving.Aeson

import HomeAssistant.Client

--------------------------------------------------------------------------------

-- | The name of the notifications service.
serviceName :: T.Text
serviceName :: Text
serviceName = Text
"notify"

-- | Enumerates different notification platforms that are supported by HA.
-- Different platforms have different capabilities and understand different
-- options in their payloads.
data NotificationPlatform
    -- | Generic.
    = OtherPlatform
    -- | iOS/macOS
    | Apple
    deriving (NotificationPlatform -> NotificationPlatform -> Bool
(NotificationPlatform -> NotificationPlatform -> Bool)
-> (NotificationPlatform -> NotificationPlatform -> Bool)
-> Eq NotificationPlatform
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NotificationPlatform -> NotificationPlatform -> Bool
== :: NotificationPlatform -> NotificationPlatform -> Bool
$c/= :: NotificationPlatform -> NotificationPlatform -> Bool
/= :: NotificationPlatform -> NotificationPlatform -> Bool
Eq, Int -> NotificationPlatform -> ShowS
[NotificationPlatform] -> ShowS
NotificationPlatform -> String
(Int -> NotificationPlatform -> ShowS)
-> (NotificationPlatform -> String)
-> ([NotificationPlatform] -> ShowS)
-> Show NotificationPlatform
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NotificationPlatform -> ShowS
showsPrec :: Int -> NotificationPlatform -> ShowS
$cshow :: NotificationPlatform -> String
show :: NotificationPlatform -> String
$cshowList :: [NotificationPlatform] -> ShowS
showList :: [NotificationPlatform] -> ShowS
Show)

-- |
-- See https://companion.home-assistant.io/docs/notifications/actionable-notifications.
data NotificationAction = MkNotificationAction {
    -- | The text to display on the button.
    NotificationAction -> Text
notificationActionTitle :: T.Text,
    -- | The key data to send to HA when the button is pressed.
    --
    -- Can be set to the string @"REPLY"@ to prompt for the string to return to HA.
    --
    -- On Android, this must be set to the string @"URI"@ to open the optional URI that can be specified.
    NotificationAction -> Text
notificationActionAction :: T.Text,
    -- | Optional, the URI to open when the button is pressed.
    NotificationAction -> Maybe Text
notificationActionURI :: Maybe T.Text,
    -- | Set to @"textInput"@ to prompt for text.
    NotificationAction -> Maybe Text
notificationActionBehavior :: Maybe T.Text
} deriving ((forall x. NotificationAction -> Rep NotificationAction x)
-> (forall x. Rep NotificationAction x -> NotificationAction)
-> Generic NotificationAction
forall x. Rep NotificationAction x -> NotificationAction
forall x. NotificationAction -> Rep NotificationAction x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NotificationAction -> Rep NotificationAction x
from :: forall x. NotificationAction -> Rep NotificationAction x
$cto :: forall x. Rep NotificationAction x -> NotificationAction
to :: forall x. Rep NotificationAction x -> NotificationAction
Generic, NotificationAction -> NotificationAction -> Bool
(NotificationAction -> NotificationAction -> Bool)
-> (NotificationAction -> NotificationAction -> Bool)
-> Eq NotificationAction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NotificationAction -> NotificationAction -> Bool
== :: NotificationAction -> NotificationAction -> Bool
$c/= :: NotificationAction -> NotificationAction -> Bool
/= :: NotificationAction -> NotificationAction -> Bool
Eq, Int -> NotificationAction -> ShowS
[NotificationAction] -> ShowS
NotificationAction -> String
(Int -> NotificationAction -> ShowS)
-> (NotificationAction -> String)
-> ([NotificationAction] -> ShowS)
-> Show NotificationAction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NotificationAction -> ShowS
showsPrec :: Int -> NotificationAction -> ShowS
$cshow :: NotificationAction -> String
show :: NotificationAction -> String
$cshowList :: [NotificationAction] -> ShowS
showList :: [NotificationAction] -> ShowS
Show)
  deriving (Maybe NotificationAction
Value -> Parser [NotificationAction]
Value -> Parser NotificationAction
(Value -> Parser NotificationAction)
-> (Value -> Parser [NotificationAction])
-> Maybe NotificationAction
-> FromJSON NotificationAction
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser NotificationAction
parseJSON :: Value -> Parser NotificationAction
$cparseJSONList :: Value -> Parser [NotificationAction]
parseJSONList :: Value -> Parser [NotificationAction]
$comittedField :: Maybe NotificationAction
omittedField :: Maybe NotificationAction
FromJSON, [NotificationAction] -> Value
[NotificationAction] -> Encoding
NotificationAction -> Bool
NotificationAction -> Value
NotificationAction -> Encoding
(NotificationAction -> Value)
-> (NotificationAction -> Encoding)
-> ([NotificationAction] -> Value)
-> ([NotificationAction] -> Encoding)
-> (NotificationAction -> Bool)
-> ToJSON NotificationAction
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: NotificationAction -> Value
toJSON :: NotificationAction -> Value
$ctoEncoding :: NotificationAction -> Encoding
toEncoding :: NotificationAction -> Encoding
$ctoJSONList :: [NotificationAction] -> Value
toJSONList :: [NotificationAction] -> Value
$ctoEncodingList :: [NotificationAction] -> Encoding
toEncodingList :: [NotificationAction] -> Encoding
$comitField :: NotificationAction -> Bool
omitField :: NotificationAction -> Bool
ToJSON) via CustomJSON (JSONOptions "notificationAction") NotificationAction

data AppleNotificationData = MkAppleNotificationData {
    -- | A URI to open when the notification is clicked on,
    -- see https://companion.home-assistant.io/docs/notifications/notifications-basic/#opening-a-url
    AppleNotificationData -> Text
appleNotificationUrl :: T.Text,
    -- | A list of actions that should be available as buttons when the notification is pressed.
    AppleNotificationData -> Maybe [NotificationAction]
appleNotificationAction :: Maybe [NotificationAction]
} deriving ((forall x. AppleNotificationData -> Rep AppleNotificationData x)
-> (forall x. Rep AppleNotificationData x -> AppleNotificationData)
-> Generic AppleNotificationData
forall x. Rep AppleNotificationData x -> AppleNotificationData
forall x. AppleNotificationData -> Rep AppleNotificationData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AppleNotificationData -> Rep AppleNotificationData x
from :: forall x. AppleNotificationData -> Rep AppleNotificationData x
$cto :: forall x. Rep AppleNotificationData x -> AppleNotificationData
to :: forall x. Rep AppleNotificationData x -> AppleNotificationData
Generic, AppleNotificationData -> AppleNotificationData -> Bool
(AppleNotificationData -> AppleNotificationData -> Bool)
-> (AppleNotificationData -> AppleNotificationData -> Bool)
-> Eq AppleNotificationData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AppleNotificationData -> AppleNotificationData -> Bool
== :: AppleNotificationData -> AppleNotificationData -> Bool
$c/= :: AppleNotificationData -> AppleNotificationData -> Bool
/= :: AppleNotificationData -> AppleNotificationData -> Bool
Eq, Int -> AppleNotificationData -> ShowS
[AppleNotificationData] -> ShowS
AppleNotificationData -> String
(Int -> AppleNotificationData -> ShowS)
-> (AppleNotificationData -> String)
-> ([AppleNotificationData] -> ShowS)
-> Show AppleNotificationData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AppleNotificationData -> ShowS
showsPrec :: Int -> AppleNotificationData -> ShowS
$cshow :: AppleNotificationData -> String
show :: AppleNotificationData -> String
$cshowList :: [AppleNotificationData] -> ShowS
showList :: [AppleNotificationData] -> ShowS
Show)
  deriving (Maybe AppleNotificationData
Value -> Parser [AppleNotificationData]
Value -> Parser AppleNotificationData
(Value -> Parser AppleNotificationData)
-> (Value -> Parser [AppleNotificationData])
-> Maybe AppleNotificationData
-> FromJSON AppleNotificationData
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser AppleNotificationData
parseJSON :: Value -> Parser AppleNotificationData
$cparseJSONList :: Value -> Parser [AppleNotificationData]
parseJSONList :: Value -> Parser [AppleNotificationData]
$comittedField :: Maybe AppleNotificationData
omittedField :: Maybe AppleNotificationData
FromJSON, [AppleNotificationData] -> Value
[AppleNotificationData] -> Encoding
AppleNotificationData -> Bool
AppleNotificationData -> Value
AppleNotificationData -> Encoding
(AppleNotificationData -> Value)
-> (AppleNotificationData -> Encoding)
-> ([AppleNotificationData] -> Value)
-> ([AppleNotificationData] -> Encoding)
-> (AppleNotificationData -> Bool)
-> ToJSON AppleNotificationData
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: AppleNotificationData -> Value
toJSON :: AppleNotificationData -> Value
$ctoEncoding :: AppleNotificationData -> Encoding
toEncoding :: AppleNotificationData -> Encoding
$ctoJSONList :: [AppleNotificationData] -> Value
toJSONList :: [AppleNotificationData] -> Value
$ctoEncodingList :: [AppleNotificationData] -> Encoding
toEncodingList :: [AppleNotificationData] -> Encoding
$comitField :: AppleNotificationData -> Bool
omitField :: AppleNotificationData -> Bool
ToJSON) via CustomJSON (JSONOptions "appleNotification") AppleNotificationData


-- | Represents platform-specific data for a notification.
data NotificationData (platform :: NotificationPlatform) where
    -- | A general constructor that can be used to pass arbitrary JSON data to
    -- the notification provider.
    OtherNotificationData :: Value -> NotificationData 'OtherPlatform
    AppleNotificationData :: AppleNotificationData -> NotificationData 'Apple

instance Eq (NotificationData platform) where
    (OtherNotificationData Value
l) == :: NotificationData platform -> NotificationData platform -> Bool
== (OtherNotificationData Value
r) = Value
l Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
== Value
r
    (AppleNotificationData AppleNotificationData
l) == (AppleNotificationData AppleNotificationData
r) = AppleNotificationData
l AppleNotificationData -> AppleNotificationData -> Bool
forall a. Eq a => a -> a -> Bool
== AppleNotificationData
r

instance Show (NotificationData platform) where
    show :: NotificationData platform -> String
show (OtherNotificationData Value
d) = Value -> String
forall a. Show a => a -> String
show Value
d
    show (AppleNotificationData AppleNotificationData
d) = AppleNotificationData -> String
forall a. Show a => a -> String
show AppleNotificationData
d

instance FromJSON (NotificationData OtherPlatform) where
    parseJSON :: Value -> Parser (NotificationData 'OtherPlatform)
parseJSON = (Value -> NotificationData 'OtherPlatform)
-> Parser Value -> Parser (NotificationData 'OtherPlatform)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Value -> NotificationData 'OtherPlatform
OtherNotificationData (Parser Value -> Parser (NotificationData 'OtherPlatform))
-> (Value -> Parser Value)
-> Value
-> Parser (NotificationData 'OtherPlatform)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser Value
forall a. FromJSON a => Value -> Parser a
parseJSON

instance FromJSON (NotificationData Apple) where
    parseJSON :: Value -> Parser (NotificationData 'Apple)
parseJSON = (AppleNotificationData -> NotificationData 'Apple)
-> Parser AppleNotificationData -> Parser (NotificationData 'Apple)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AppleNotificationData -> NotificationData 'Apple
AppleNotificationData (Parser AppleNotificationData -> Parser (NotificationData 'Apple))
-> (Value -> Parser AppleNotificationData)
-> Value
-> Parser (NotificationData 'Apple)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser AppleNotificationData
forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToJSON (NotificationData platform) where
    toJSON :: NotificationData platform -> Value
toJSON (OtherNotificationData Value
v) = Value -> Value
forall a. ToJSON a => a -> Value
toJSON Value
v
    toJSON (AppleNotificationData AppleNotificationData
v) = AppleNotificationData -> Value
forall a. ToJSON a => a -> Value
toJSON AppleNotificationData
v

data Notification platform = MkNotification {
    -- | The notification message. This is required.
    forall (platform :: NotificationPlatform).
Notification platform -> Text
notificationMessage :: T.Text,
    -- | The title of the notification. Will default to the Home Assistant app name on the
    -- target device if not set.
    forall (platform :: NotificationPlatform).
Notification platform -> Maybe Text
notificationTitle :: Maybe T.Text,
    -- | Platform-specific data associated with the notification.
    --
    -- See the constructors of `NotificationData` for more information and the documentation
    -- at https://www.home-assistant.io/integrations/notify/
    forall (platform :: NotificationPlatform).
Notification platform -> Maybe (NotificationData platform)
notificationData :: Maybe (NotificationData platform),
    -- | Platform-specific target for the notification.
    forall (platform :: NotificationPlatform).
Notification platform -> Maybe Value
notificationTarget :: Maybe Value
} deriving ((forall x. Notification platform -> Rep (Notification platform) x)
-> (forall x.
    Rep (Notification platform) x -> Notification platform)
-> Generic (Notification platform)
forall x. Rep (Notification platform) x -> Notification platform
forall x. Notification platform -> Rep (Notification platform) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (platform :: NotificationPlatform) x.
Rep (Notification platform) x -> Notification platform
forall (platform :: NotificationPlatform) x.
Notification platform -> Rep (Notification platform) x
$cfrom :: forall (platform :: NotificationPlatform) x.
Notification platform -> Rep (Notification platform) x
from :: forall x. Notification platform -> Rep (Notification platform) x
$cto :: forall (platform :: NotificationPlatform) x.
Rep (Notification platform) x -> Notification platform
to :: forall x. Rep (Notification platform) x -> Notification platform
Generic, Notification platform -> Notification platform -> Bool
(Notification platform -> Notification platform -> Bool)
-> (Notification platform -> Notification platform -> Bool)
-> Eq (Notification platform)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (platform :: NotificationPlatform).
Notification platform -> Notification platform -> Bool
$c== :: forall (platform :: NotificationPlatform).
Notification platform -> Notification platform -> Bool
== :: Notification platform -> Notification platform -> Bool
$c/= :: forall (platform :: NotificationPlatform).
Notification platform -> Notification platform -> Bool
/= :: Notification platform -> Notification platform -> Bool
Eq, Int -> Notification platform -> ShowS
[Notification platform] -> ShowS
Notification platform -> String
(Int -> Notification platform -> ShowS)
-> (Notification platform -> String)
-> ([Notification platform] -> ShowS)
-> Show (Notification platform)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (platform :: NotificationPlatform).
Int -> Notification platform -> ShowS
forall (platform :: NotificationPlatform).
[Notification platform] -> ShowS
forall (platform :: NotificationPlatform).
Notification platform -> String
$cshowsPrec :: forall (platform :: NotificationPlatform).
Int -> Notification platform -> ShowS
showsPrec :: Int -> Notification platform -> ShowS
$cshow :: forall (platform :: NotificationPlatform).
Notification platform -> String
show :: Notification platform -> String
$cshowList :: forall (platform :: NotificationPlatform).
[Notification platform] -> ShowS
showList :: [Notification platform] -> ShowS
Show)
  deriving ([Notification platform] -> Value
[Notification platform] -> Encoding
Notification platform -> Bool
Notification platform -> Value
Notification platform -> Encoding
(Notification platform -> Value)
-> (Notification platform -> Encoding)
-> ([Notification platform] -> Value)
-> ([Notification platform] -> Encoding)
-> (Notification platform -> Bool)
-> ToJSON (Notification platform)
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
forall (platform :: NotificationPlatform).
[Notification platform] -> Value
forall (platform :: NotificationPlatform).
[Notification platform] -> Encoding
forall (platform :: NotificationPlatform).
Notification platform -> Bool
forall (platform :: NotificationPlatform).
Notification platform -> Value
forall (platform :: NotificationPlatform).
Notification platform -> Encoding
$ctoJSON :: forall (platform :: NotificationPlatform).
Notification platform -> Value
toJSON :: Notification platform -> Value
$ctoEncoding :: forall (platform :: NotificationPlatform).
Notification platform -> Encoding
toEncoding :: Notification platform -> Encoding
$ctoJSONList :: forall (platform :: NotificationPlatform).
[Notification platform] -> Value
toJSONList :: [Notification platform] -> Value
$ctoEncodingList :: forall (platform :: NotificationPlatform).
[Notification platform] -> Encoding
toEncodingList :: [Notification platform] -> Encoding
$comitField :: forall (platform :: NotificationPlatform).
Notification platform -> Bool
omitField :: Notification platform -> Bool
ToJSON) via CustomJSON (JSONOptions "notification") (Notification platform)

instance FromJSON (Notification OtherPlatform) where
    parseJSON :: Value -> Parser (Notification 'OtherPlatform)
parseJSON = String
-> (Object -> Parser (Notification 'OtherPlatform))
-> Value
-> Parser (Notification 'OtherPlatform)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Notification" ((Object -> Parser (Notification 'OtherPlatform))
 -> Value -> Parser (Notification 'OtherPlatform))
-> (Object -> Parser (Notification 'OtherPlatform))
-> Value
-> Parser (Notification 'OtherPlatform)
forall a b. (a -> b) -> a -> b
$ \Object
v ->
        Text
-> Maybe Text
-> Maybe (NotificationData 'OtherPlatform)
-> Maybe Value
-> Notification 'OtherPlatform
forall (platform :: NotificationPlatform).
Text
-> Maybe Text
-> Maybe (NotificationData platform)
-> Maybe Value
-> Notification platform
MkNotification (Text
 -> Maybe Text
 -> Maybe (NotificationData 'OtherPlatform)
 -> Maybe Value
 -> Notification 'OtherPlatform)
-> Parser Text
-> Parser
     (Maybe Text
      -> Maybe (NotificationData 'OtherPlatform)
      -> Maybe Value
      -> Notification 'OtherPlatform)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"message" Parser
  (Maybe Text
   -> Maybe (NotificationData 'OtherPlatform)
   -> Maybe Value
   -> Notification 'OtherPlatform)
-> Parser (Maybe Text)
-> Parser
     (Maybe (NotificationData 'OtherPlatform)
      -> Maybe Value -> Notification 'OtherPlatform)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"title" Parser
  (Maybe (NotificationData 'OtherPlatform)
   -> Maybe Value -> Notification 'OtherPlatform)
-> Parser (Maybe (NotificationData 'OtherPlatform))
-> Parser (Maybe Value -> Notification 'OtherPlatform)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe (NotificationData 'OtherPlatform))
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"data" Parser (Maybe Value -> Notification 'OtherPlatform)
-> Parser (Maybe Value) -> Parser (Notification 'OtherPlatform)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser (Maybe Value)
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"target"

-- | 'notification' @message@ constructs a `Notification` containing @message@.
-- Can be used to then change other properties of the resulting `Notification`.
notification :: T.Text -> Notification platform
notification :: forall (platform :: NotificationPlatform).
Text -> Notification platform
notification Text
message = MkNotification{
    notificationMessage :: Text
notificationMessage = Text
message,
    notificationTitle :: Maybe Text
notificationTitle = Maybe Text
forall a. Maybe a
Nothing,
    notificationData :: Maybe (NotificationData platform)
notificationData = Maybe (NotificationData platform)
forall a. Maybe a
Nothing,
    notificationTarget :: Maybe Value
notificationTarget = Maybe Value
forall a. Maybe a
Nothing
}

-- | 'setNotificationTitle' @title notification@ sets @notification@'s @title@.
setNotificationTitle ::
    Maybe T.Text ->
    Notification platform ->
    Notification platform
setNotificationTitle :: forall (platform :: NotificationPlatform).
Maybe Text -> Notification platform -> Notification platform
setNotificationTitle Maybe Text
title Notification platform
n = Notification platform
n{ notificationTitle = title }

-- | 'setNotificationData' @data notification@ sets @notification@'s @data@.
setNotificationData ::
    Maybe (NotificationData platform) ->
    Notification platform ->
    Notification platform
setNotificationData :: forall (platform :: NotificationPlatform).
Maybe (NotificationData platform)
-> Notification platform -> Notification platform
setNotificationData Maybe (NotificationData platform)
d Notification platform
n = Notification platform
n{ notificationData = d }

-- | 'notify' @device notification@ is a wrapper around `callService` that uses
-- the notifications service to send @notification@ to @device@.
notify :: T.Text -> Notification platform -> HA Value
notify :: forall (platform :: NotificationPlatform).
Text -> Notification platform -> HA Value
notify Text
device = Text -> Text -> Maybe Value -> HA Value
callService Text
serviceName Text
device (Maybe Value -> HA Value)
-> (Notification platform -> Maybe Value)
-> Notification platform
-> HA Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Maybe Value
forall a. a -> Maybe a
Just (Value -> Maybe Value)
-> (Notification platform -> Value)
-> Notification platform
-> Maybe Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Notification platform -> Value
forall a. ToJSON a => a -> Value
toJSON

--------------------------------------------------------------------------------