-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}

module Duckling.AmountOfMoney.Types where

import Control.DeepSeq
import Data.Aeson
import Data.Hashable
import Data.Text (Text)
import GHC.Generics
import Prelude
import qualified Data.HashMap.Strict as H

import Duckling.Resolve (Resolve(..), Options(..))

data Currency
  -- ambiguous
  = Cent
  | Dinar
  | Dirham
  | Dollar
  | Pound
  | Rial
  | Riyal
  | Unnamed -- e.g. bucks
  -- unambiguous
  | AED
  | AUD
  | BGN
  | BRL
  | BYN
  | CAD
  | CHF
  | CNY
  | CZK
  | DKK
  | EGP
  | EUR
  | GBP
  | HKD
  | HRK
  | IDR
  | ILS
  | INR
  | IQD
  | JMD
  | JOD
  | JPY
  | GEL
  | KRW
  | KWD
  | LBP
  | MAD
  | MNT
  | MYR
  | NOK
  | NZD
  | PKR
  | PLN
  | PTS
  | QAR
  | RON
  | RUB
  | SAR
  | SEK
  | SGD
  | THB
  | TTD
  | USD
  | VND
  | ZAR
  | UAH
  | TRY
  deriving (Currency -> Currency -> Bool
(Currency -> Currency -> Bool)
-> (Currency -> Currency -> Bool) -> Eq Currency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Currency -> Currency -> Bool
$c/= :: Currency -> Currency -> Bool
== :: Currency -> Currency -> Bool
$c== :: Currency -> Currency -> Bool
Eq, (forall x. Currency -> Rep Currency x)
-> (forall x. Rep Currency x -> Currency) -> Generic Currency
forall x. Rep Currency x -> Currency
forall x. Currency -> Rep Currency x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Currency x -> Currency
$cfrom :: forall x. Currency -> Rep Currency x
Generic, Int -> Currency -> Int
Currency -> Int
(Int -> Currency -> Int) -> (Currency -> Int) -> Hashable Currency
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Currency -> Int
$chash :: Currency -> Int
hashWithSalt :: Int -> Currency -> Int
$chashWithSalt :: Int -> Currency -> Int
Hashable, Int -> Currency -> ShowS
[Currency] -> ShowS
Currency -> String
(Int -> Currency -> ShowS)
-> (Currency -> String) -> ([Currency] -> ShowS) -> Show Currency
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Currency] -> ShowS
$cshowList :: [Currency] -> ShowS
show :: Currency -> String
$cshow :: Currency -> String
showsPrec :: Int -> Currency -> ShowS
$cshowsPrec :: Int -> Currency -> ShowS
Show, Eq Currency
Eq Currency
-> (Currency -> Currency -> Ordering)
-> (Currency -> Currency -> Bool)
-> (Currency -> Currency -> Bool)
-> (Currency -> Currency -> Bool)
-> (Currency -> Currency -> Bool)
-> (Currency -> Currency -> Currency)
-> (Currency -> Currency -> Currency)
-> Ord Currency
Currency -> Currency -> Bool
Currency -> Currency -> Ordering
Currency -> Currency -> Currency
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 :: Currency -> Currency -> Currency
$cmin :: Currency -> Currency -> Currency
max :: Currency -> Currency -> Currency
$cmax :: Currency -> Currency -> Currency
>= :: Currency -> Currency -> Bool
$c>= :: Currency -> Currency -> Bool
> :: Currency -> Currency -> Bool
$c> :: Currency -> Currency -> Bool
<= :: Currency -> Currency -> Bool
$c<= :: Currency -> Currency -> Bool
< :: Currency -> Currency -> Bool
$c< :: Currency -> Currency -> Bool
compare :: Currency -> Currency -> Ordering
$ccompare :: Currency -> Currency -> Ordering
$cp1Ord :: Eq Currency
Ord, Currency -> ()
(Currency -> ()) -> NFData Currency
forall a. (a -> ()) -> NFData a
rnf :: Currency -> ()
$crnf :: Currency -> ()
NFData)

instance ToJSON Currency where
  toJSON :: Currency -> Value
toJSON Currency
Cent    = Value
"cent"
  toJSON Currency
Dollar  = Value
"$"
  toJSON Currency
Pound   = Value
"\x00a3"
  toJSON Currency
Dinar   = Value
"dinar"
  toJSON Currency
Dirham  = Value
"dirham"
  toJSON Currency
Rial    = Value
"rial"
  toJSON Currency
Riyal   = Value
"riyal"
  toJSON Currency
Unnamed = Value
"unknown"
  toJSON Currency
AED     = Value
"AED"
  toJSON Currency
AUD     = Value
"AUD"
  toJSON Currency
BGN     = Value
"BGN"
  toJSON Currency
BRL     = Value
"BRL"
  toJSON Currency
BYN     = Value
"BYN"
  toJSON Currency
CAD     = Value
"CAD"
  toJSON Currency
CHF     = Value
"CHF"
  toJSON Currency
CNY     = Value
"CNY"
  toJSON Currency
CZK     = Value
"CZK"
  toJSON Currency
DKK     = Value
"DKK"
  toJSON Currency
EGP     = Value
"EGP"
  toJSON Currency
EUR     = Value
"EUR"
  toJSON Currency
GBP     = Value
"GBP"
  toJSON Currency
HKD     = Value
"HKD"
  toJSON Currency
HRK     = Value
"HRK"
  toJSON Currency
IDR     = Value
"IDR"
  toJSON Currency
ILS     = Value
"ILS"
  toJSON Currency
IQD     = Value
"IQD"
  toJSON Currency
INR     = Value
"INR"
  toJSON Currency
JMD     = Value
"JMD"
  toJSON Currency
JOD     = Value
"JOD"
  toJSON Currency
JPY     = Value
"JPY"
  toJSON Currency
GEL     = Value
"GEL"
  toJSON Currency
KRW     = Value
"KRW"
  toJSON Currency
KWD     = Value
"KWD"
  toJSON Currency
LBP     = Value
"LBP"
  toJSON Currency
MAD     = Value
"MAD"
  toJSON Currency
MNT     = Value
"MNT"
  toJSON Currency
MYR     = Value
"MYR"
  toJSON Currency
NOK     = Value
"NOK"
  toJSON Currency
NZD     = Value
"NZD"
  toJSON Currency
PTS     = Value
"PTS"
  toJSON Currency
PKR     = Value
"PKR"
  toJSON Currency
PLN     = Value
"PLN"
  toJSON Currency
QAR     = Value
"QAR"
  toJSON Currency
RON     = Value
"RON"
  toJSON Currency
RUB     = Value
"RUB"
  toJSON Currency
SAR     = Value
"SAR"
  toJSON Currency
SEK     = Value
"SEK"
  toJSON Currency
SGD     = Value
"SGD"
  toJSON Currency
THB     = Value
"THB"
  toJSON Currency
TTD     = Value
"TTD"
  toJSON Currency
USD     = Value
"USD"
  toJSON Currency
VND     = Value
"VND"
  toJSON Currency
ZAR     = Value
"ZAR"
  toJSON Currency
UAH     = Value
"UAH"
  toJSON Currency
TRY     = Value
"TRY"

data AmountOfMoneyData = AmountOfMoneyData
  { AmountOfMoneyData -> Maybe Double
value    :: Maybe Double
  , AmountOfMoneyData -> Currency
currency :: Currency
  , AmountOfMoneyData -> Maybe Double
minValue :: Maybe Double
  , AmountOfMoneyData -> Maybe Double
maxValue :: Maybe Double
  , AmountOfMoneyData -> Bool
latent   :: Bool
  }
  deriving (AmountOfMoneyData -> AmountOfMoneyData -> Bool
(AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> (AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> Eq AmountOfMoneyData
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c/= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
== :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c== :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
Eq, (forall x. AmountOfMoneyData -> Rep AmountOfMoneyData x)
-> (forall x. Rep AmountOfMoneyData x -> AmountOfMoneyData)
-> Generic AmountOfMoneyData
forall x. Rep AmountOfMoneyData x -> AmountOfMoneyData
forall x. AmountOfMoneyData -> Rep AmountOfMoneyData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep AmountOfMoneyData x -> AmountOfMoneyData
$cfrom :: forall x. AmountOfMoneyData -> Rep AmountOfMoneyData x
Generic, Int -> AmountOfMoneyData -> Int
AmountOfMoneyData -> Int
(Int -> AmountOfMoneyData -> Int)
-> (AmountOfMoneyData -> Int) -> Hashable AmountOfMoneyData
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: AmountOfMoneyData -> Int
$chash :: AmountOfMoneyData -> Int
hashWithSalt :: Int -> AmountOfMoneyData -> Int
$chashWithSalt :: Int -> AmountOfMoneyData -> Int
Hashable, Int -> AmountOfMoneyData -> ShowS
[AmountOfMoneyData] -> ShowS
AmountOfMoneyData -> String
(Int -> AmountOfMoneyData -> ShowS)
-> (AmountOfMoneyData -> String)
-> ([AmountOfMoneyData] -> ShowS)
-> Show AmountOfMoneyData
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AmountOfMoneyData] -> ShowS
$cshowList :: [AmountOfMoneyData] -> ShowS
show :: AmountOfMoneyData -> String
$cshow :: AmountOfMoneyData -> String
showsPrec :: Int -> AmountOfMoneyData -> ShowS
$cshowsPrec :: Int -> AmountOfMoneyData -> ShowS
Show, Eq AmountOfMoneyData
Eq AmountOfMoneyData
-> (AmountOfMoneyData -> AmountOfMoneyData -> Ordering)
-> (AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> (AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> (AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> (AmountOfMoneyData -> AmountOfMoneyData -> Bool)
-> (AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData)
-> (AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData)
-> Ord AmountOfMoneyData
AmountOfMoneyData -> AmountOfMoneyData -> Bool
AmountOfMoneyData -> AmountOfMoneyData -> Ordering
AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData
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 :: AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData
$cmin :: AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData
max :: AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData
$cmax :: AmountOfMoneyData -> AmountOfMoneyData -> AmountOfMoneyData
>= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c>= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
> :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c> :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
<= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c<= :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
< :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
$c< :: AmountOfMoneyData -> AmountOfMoneyData -> Bool
compare :: AmountOfMoneyData -> AmountOfMoneyData -> Ordering
$ccompare :: AmountOfMoneyData -> AmountOfMoneyData -> Ordering
$cp1Ord :: Eq AmountOfMoneyData
Ord, AmountOfMoneyData -> ()
(AmountOfMoneyData -> ()) -> NFData AmountOfMoneyData
forall a. (a -> ()) -> NFData a
rnf :: AmountOfMoneyData -> ()
$crnf :: AmountOfMoneyData -> ()
NFData)

instance Resolve AmountOfMoneyData where
  type ResolvedValue AmountOfMoneyData = AmountOfMoneyValue
  resolve :: Context
-> Options
-> AmountOfMoneyData
-> Maybe (ResolvedValue AmountOfMoneyData, Bool)
resolve Context
_ Options {withLatent :: Options -> Bool
withLatent = Bool
False} AmountOfMoneyData {latent :: AmountOfMoneyData -> Bool
latent = Bool
True} =
    Maybe (ResolvedValue AmountOfMoneyData, Bool)
forall a. Maybe a
Nothing
  resolve Context
_ Options
_ AmountOfMoneyData {value :: AmountOfMoneyData -> Maybe Double
value = Maybe Double
Nothing, minValue :: AmountOfMoneyData -> Maybe Double
minValue = Maybe Double
Nothing
                              , maxValue :: AmountOfMoneyData -> Maybe Double
maxValue = Maybe Double
Nothing} =
    Maybe (ResolvedValue AmountOfMoneyData, Bool)
forall a. Maybe a
Nothing
  resolve Context
_ Options
_ AmountOfMoneyData {value :: AmountOfMoneyData -> Maybe Double
value = Just Double
value, Currency
currency :: Currency
currency :: AmountOfMoneyData -> Currency
currency, Bool
latent :: Bool
latent :: AmountOfMoneyData -> Bool
latent} =
    (AmountOfMoneyValue, Bool) -> Maybe (AmountOfMoneyValue, Bool)
forall a. a -> Maybe a
Just (Currency -> Double -> AmountOfMoneyValue
simple Currency
currency Double
value, Bool
latent)
  resolve Context
_ Options
_ AmountOfMoneyData {value :: AmountOfMoneyData -> Maybe Double
value = Maybe Double
Nothing, currency :: AmountOfMoneyData -> Currency
currency = Currency
c
                              , minValue :: AmountOfMoneyData -> Maybe Double
minValue = Just Double
from, maxValue :: AmountOfMoneyData -> Maybe Double
maxValue = Just Double
to
                              , Bool
latent :: Bool
latent :: AmountOfMoneyData -> Bool
latent} =
    (AmountOfMoneyValue, Bool) -> Maybe (AmountOfMoneyValue, Bool)
forall a. a -> Maybe a
Just (Currency -> (Double, Double) -> AmountOfMoneyValue
between Currency
c (Double
from, Double
to), Bool
latent)
  resolve Context
_ Options
_ AmountOfMoneyData {value :: AmountOfMoneyData -> Maybe Double
value = Maybe Double
Nothing, currency :: AmountOfMoneyData -> Currency
currency = Currency
c
                              , minValue :: AmountOfMoneyData -> Maybe Double
minValue = Just Double
v, maxValue :: AmountOfMoneyData -> Maybe Double
maxValue = Maybe Double
Nothing
                              , Bool
latent :: Bool
latent :: AmountOfMoneyData -> Bool
latent} =
    (AmountOfMoneyValue, Bool) -> Maybe (AmountOfMoneyValue, Bool)
forall a. a -> Maybe a
Just (Currency -> Double -> AmountOfMoneyValue
above Currency
c Double
v, Bool
latent)
  resolve Context
_ Options
_ AmountOfMoneyData {value :: AmountOfMoneyData -> Maybe Double
value = Maybe Double
Nothing, currency :: AmountOfMoneyData -> Currency
currency = Currency
c
                              , minValue :: AmountOfMoneyData -> Maybe Double
minValue = Maybe Double
Nothing, maxValue :: AmountOfMoneyData -> Maybe Double
maxValue = Just Double
v
                              , Bool
latent :: Bool
latent :: AmountOfMoneyData -> Bool
latent} =
    (AmountOfMoneyValue, Bool) -> Maybe (AmountOfMoneyValue, Bool)
forall a. a -> Maybe a
Just (Currency -> Double -> AmountOfMoneyValue
under Currency
c Double
v, Bool
latent)

amountOfMoneyData' :: AmountOfMoneyData
amountOfMoneyData' :: AmountOfMoneyData
amountOfMoneyData' = AmountOfMoneyData :: Maybe Double
-> Currency
-> Maybe Double
-> Maybe Double
-> Bool
-> AmountOfMoneyData
AmountOfMoneyData
  { value :: Maybe Double
value = Maybe Double
forall a. Maybe a
Nothing
  , currency :: Currency
currency = Currency
Unnamed
  , minValue :: Maybe Double
minValue = Maybe Double
forall a. Maybe a
Nothing
  , maxValue :: Maybe Double
maxValue = Maybe Double
forall a. Maybe a
Nothing
  , latent :: Bool
latent = Bool
False
  }

data IntervalDirection = Above | Under
  deriving (IntervalDirection -> IntervalDirection -> Bool
(IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> Eq IntervalDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalDirection -> IntervalDirection -> Bool
$c/= :: IntervalDirection -> IntervalDirection -> Bool
== :: IntervalDirection -> IntervalDirection -> Bool
$c== :: IntervalDirection -> IntervalDirection -> Bool
Eq, (forall x. IntervalDirection -> Rep IntervalDirection x)
-> (forall x. Rep IntervalDirection x -> IntervalDirection)
-> Generic IntervalDirection
forall x. Rep IntervalDirection x -> IntervalDirection
forall x. IntervalDirection -> Rep IntervalDirection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IntervalDirection x -> IntervalDirection
$cfrom :: forall x. IntervalDirection -> Rep IntervalDirection x
Generic, Int -> IntervalDirection -> Int
IntervalDirection -> Int
(Int -> IntervalDirection -> Int)
-> (IntervalDirection -> Int) -> Hashable IntervalDirection
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: IntervalDirection -> Int
$chash :: IntervalDirection -> Int
hashWithSalt :: Int -> IntervalDirection -> Int
$chashWithSalt :: Int -> IntervalDirection -> Int
Hashable, Eq IntervalDirection
Eq IntervalDirection
-> (IntervalDirection -> IntervalDirection -> Ordering)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> Bool)
-> (IntervalDirection -> IntervalDirection -> IntervalDirection)
-> (IntervalDirection -> IntervalDirection -> IntervalDirection)
-> Ord IntervalDirection
IntervalDirection -> IntervalDirection -> Bool
IntervalDirection -> IntervalDirection -> Ordering
IntervalDirection -> IntervalDirection -> IntervalDirection
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 :: IntervalDirection -> IntervalDirection -> IntervalDirection
$cmin :: IntervalDirection -> IntervalDirection -> IntervalDirection
max :: IntervalDirection -> IntervalDirection -> IntervalDirection
$cmax :: IntervalDirection -> IntervalDirection -> IntervalDirection
>= :: IntervalDirection -> IntervalDirection -> Bool
$c>= :: IntervalDirection -> IntervalDirection -> Bool
> :: IntervalDirection -> IntervalDirection -> Bool
$c> :: IntervalDirection -> IntervalDirection -> Bool
<= :: IntervalDirection -> IntervalDirection -> Bool
$c<= :: IntervalDirection -> IntervalDirection -> Bool
< :: IntervalDirection -> IntervalDirection -> Bool
$c< :: IntervalDirection -> IntervalDirection -> Bool
compare :: IntervalDirection -> IntervalDirection -> Ordering
$ccompare :: IntervalDirection -> IntervalDirection -> Ordering
$cp1Ord :: Eq IntervalDirection
Ord, Int -> IntervalDirection -> ShowS
[IntervalDirection] -> ShowS
IntervalDirection -> String
(Int -> IntervalDirection -> ShowS)
-> (IntervalDirection -> String)
-> ([IntervalDirection] -> ShowS)
-> Show IntervalDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IntervalDirection] -> ShowS
$cshowList :: [IntervalDirection] -> ShowS
show :: IntervalDirection -> String
$cshow :: IntervalDirection -> String
showsPrec :: Int -> IntervalDirection -> ShowS
$cshowsPrec :: Int -> IntervalDirection -> ShowS
Show, IntervalDirection -> ()
(IntervalDirection -> ()) -> NFData IntervalDirection
forall a. (a -> ()) -> NFData a
rnf :: IntervalDirection -> ()
$crnf :: IntervalDirection -> ()
NFData)

data SingleValue = SingleValue
  { SingleValue -> Currency
vCurrency :: Currency
  , SingleValue -> Double
vValue    :: Double
  }
  deriving (SingleValue -> SingleValue -> Bool
(SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool) -> Eq SingleValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SingleValue -> SingleValue -> Bool
$c/= :: SingleValue -> SingleValue -> Bool
== :: SingleValue -> SingleValue -> Bool
$c== :: SingleValue -> SingleValue -> Bool
Eq, Int -> SingleValue -> ShowS
[SingleValue] -> ShowS
SingleValue -> String
(Int -> SingleValue -> ShowS)
-> (SingleValue -> String)
-> ([SingleValue] -> ShowS)
-> Show SingleValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SingleValue] -> ShowS
$cshowList :: [SingleValue] -> ShowS
show :: SingleValue -> String
$cshow :: SingleValue -> String
showsPrec :: Int -> SingleValue -> ShowS
$cshowsPrec :: Int -> SingleValue -> ShowS
Show)

instance ToJSON SingleValue where
  toJSON :: SingleValue -> Value
toJSON SingleValue {Currency
vCurrency :: Currency
vCurrency :: SingleValue -> Currency
vCurrency, Double
vValue :: Double
vValue :: SingleValue -> Double
vValue} = [Pair] -> Value
object
    [ Text
"value" Text -> Double -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Double
vValue
    , Text
"unit"  Text -> Currency -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Currency
vCurrency
    ]

data AmountOfMoneyValue
  = SimpleValue SingleValue
  | IntervalValue (SingleValue, SingleValue)
  | OpenIntervalValue (SingleValue, IntervalDirection)
  deriving (Int -> AmountOfMoneyValue -> ShowS
[AmountOfMoneyValue] -> ShowS
AmountOfMoneyValue -> String
(Int -> AmountOfMoneyValue -> ShowS)
-> (AmountOfMoneyValue -> String)
-> ([AmountOfMoneyValue] -> ShowS)
-> Show AmountOfMoneyValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AmountOfMoneyValue] -> ShowS
$cshowList :: [AmountOfMoneyValue] -> ShowS
show :: AmountOfMoneyValue -> String
$cshow :: AmountOfMoneyValue -> String
showsPrec :: Int -> AmountOfMoneyValue -> ShowS
$cshowsPrec :: Int -> AmountOfMoneyValue -> ShowS
Show, AmountOfMoneyValue -> AmountOfMoneyValue -> Bool
(AmountOfMoneyValue -> AmountOfMoneyValue -> Bool)
-> (AmountOfMoneyValue -> AmountOfMoneyValue -> Bool)
-> Eq AmountOfMoneyValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AmountOfMoneyValue -> AmountOfMoneyValue -> Bool
$c/= :: AmountOfMoneyValue -> AmountOfMoneyValue -> Bool
== :: AmountOfMoneyValue -> AmountOfMoneyValue -> Bool
$c== :: AmountOfMoneyValue -> AmountOfMoneyValue -> Bool
Eq)

instance ToJSON AmountOfMoneyValue where
  toJSON :: AmountOfMoneyValue -> Value
toJSON (SimpleValue SingleValue
value) = case SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
value of
    Object Object
o -> Object -> Value
Object (Object -> Value) -> Object -> Value
forall a b. (a -> b) -> a -> b
$ Text -> Value -> Object -> Object
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
H.insert Text
"type" (Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text
"value" :: Text)) Object
o
    Value
_ -> Object -> Value
Object Object
forall k v. HashMap k v
H.empty
  toJSON (IntervalValue (SingleValue
from, SingleValue
to)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"from" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
from
    , Text
"to" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
to
    ]
  toJSON (OpenIntervalValue (SingleValue
from, IntervalDirection
Above)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"from" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
from
    ]
  toJSON (OpenIntervalValue (SingleValue
to, IntervalDirection
Under)) = [Pair] -> Value
object
    [ Text
"type" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Text
"interval" :: Text)
    , Text
"to" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SingleValue -> Value
forall a. ToJSON a => a -> Value
toJSON SingleValue
to
    ]

-- -----------------------------------------------------------------
-- Value helpers

simple :: Currency -> Double -> AmountOfMoneyValue
simple :: Currency -> Double -> AmountOfMoneyValue
simple Currency
c Double
v = SingleValue -> AmountOfMoneyValue
SimpleValue (SingleValue -> AmountOfMoneyValue)
-> SingleValue -> AmountOfMoneyValue
forall a b. (a -> b) -> a -> b
$ Currency -> Double -> SingleValue
single Currency
c Double
v

between :: Currency -> (Double, Double) -> AmountOfMoneyValue
between :: Currency -> (Double, Double) -> AmountOfMoneyValue
between Currency
c (Double
from, Double
to) = (SingleValue, SingleValue) -> AmountOfMoneyValue
IntervalValue (Currency -> Double -> SingleValue
single Currency
c Double
from, Currency -> Double -> SingleValue
single Currency
c Double
to)

above :: Currency -> Double -> AmountOfMoneyValue
above :: Currency -> Double -> AmountOfMoneyValue
above = IntervalDirection -> Currency -> Double -> AmountOfMoneyValue
openInterval IntervalDirection
Above

under :: Currency -> Double -> AmountOfMoneyValue
under :: Currency -> Double -> AmountOfMoneyValue
under = IntervalDirection -> Currency -> Double -> AmountOfMoneyValue
openInterval IntervalDirection
Under

openInterval :: IntervalDirection -> Currency -> Double -> AmountOfMoneyValue
openInterval :: IntervalDirection -> Currency -> Double -> AmountOfMoneyValue
openInterval IntervalDirection
direction Currency
c Double
v = (SingleValue, IntervalDirection) -> AmountOfMoneyValue
OpenIntervalValue (Currency -> Double -> SingleValue
single Currency
c Double
v, IntervalDirection
direction)

single :: Currency -> Double -> SingleValue
single :: Currency -> Double -> SingleValue
single Currency
c Double
v = SingleValue :: Currency -> Double -> SingleValue
SingleValue {vCurrency :: Currency
vCurrency = Currency
c, vValue :: Double
vValue = Double
v}