-- 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 NoRebindableSyntax #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
module Duckling.Quantity.Types where

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

data Unit
  = Bowl
  | Cup
  | Custom Text
  | Dish
  | Gram
  | Ounce
  | Pint
  | Pound
  | Quart
  | Tablespoon
  | Teaspoon
  | Unnamed
  deriving (Unit -> Unit -> Bool
(Unit -> Unit -> Bool) -> (Unit -> Unit -> Bool) -> Eq Unit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Unit -> Unit -> Bool
$c/= :: Unit -> Unit -> Bool
== :: Unit -> Unit -> Bool
$c== :: Unit -> Unit -> Bool
Eq, (forall x. Unit -> Rep Unit x)
-> (forall x. Rep Unit x -> Unit) -> Generic Unit
forall x. Rep Unit x -> Unit
forall x. Unit -> Rep Unit x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Unit x -> Unit
$cfrom :: forall x. Unit -> Rep Unit x
Generic, Int -> Unit -> Int
Unit -> Int
(Int -> Unit -> Int) -> (Unit -> Int) -> Hashable Unit
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Unit -> Int
$chash :: Unit -> Int
hashWithSalt :: Int -> Unit -> Int
$chashWithSalt :: Int -> Unit -> Int
Hashable, Eq Unit
Eq Unit
-> (Unit -> Unit -> Ordering)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Bool)
-> (Unit -> Unit -> Unit)
-> (Unit -> Unit -> Unit)
-> Ord Unit
Unit -> Unit -> Bool
Unit -> Unit -> Ordering
Unit -> Unit -> Unit
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 :: Unit -> Unit -> Unit
$cmin :: Unit -> Unit -> Unit
max :: Unit -> Unit -> Unit
$cmax :: Unit -> Unit -> Unit
>= :: Unit -> Unit -> Bool
$c>= :: Unit -> Unit -> Bool
> :: Unit -> Unit -> Bool
$c> :: Unit -> Unit -> Bool
<= :: Unit -> Unit -> Bool
$c<= :: Unit -> Unit -> Bool
< :: Unit -> Unit -> Bool
$c< :: Unit -> Unit -> Bool
compare :: Unit -> Unit -> Ordering
$ccompare :: Unit -> Unit -> Ordering
$cp1Ord :: Eq Unit
Ord, Int -> Unit -> ShowS
[Unit] -> ShowS
Unit -> String
(Int -> Unit -> ShowS)
-> (Unit -> String) -> ([Unit] -> ShowS) -> Show Unit
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Unit] -> ShowS
$cshowList :: [Unit] -> ShowS
show :: Unit -> String
$cshow :: Unit -> String
showsPrec :: Int -> Unit -> ShowS
$cshowsPrec :: Int -> Unit -> ShowS
Show, Unit -> ()
(Unit -> ()) -> NFData Unit
forall a. (a -> ()) -> NFData a
rnf :: Unit -> ()
$crnf :: Unit -> ()
NFData)

instance ToJSON Unit where
  toJSON :: Unit -> Value
toJSON (Custom Text
x) = Text -> Value
String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ Text -> Text
Text.toLower Text
x
  toJSON Unit
x = Text -> Value
String (Text -> Value) -> (String -> Text) -> String -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
Text.toLower (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
Text.pack (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ Unit -> String
forall a. Show a => a -> String
show Unit
x

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

instance Resolve QuantityData where
  type ResolvedValue QuantityData = QuantityValue
  resolve :: Context
-> Options
-> QuantityData
-> Maybe (ResolvedValue QuantityData, Bool)
resolve Context
_ Options {withLatent :: Options -> Bool
withLatent = Bool
False} QuantityData {latent :: QuantityData -> Bool
latent = Bool
True}
   = Maybe (ResolvedValue QuantityData, Bool)
forall a. Maybe a
Nothing

  resolve Context
_ Options
_ QuantityData {value :: QuantityData -> Maybe Double
value = Just Double
value
                         , unit :: QuantityData -> Maybe Unit
unit = Maybe Unit
Nothing
                         , aproduct :: QuantityData -> Maybe Text
aproduct = Maybe Text
aproduct
                         , latent :: QuantityData -> Bool
latent = Bool
latent}
   = (QuantityValue, Bool) -> Maybe (QuantityValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> Maybe Text -> QuantityValue
simple Unit
Unnamed Double
value Maybe Text
aproduct, Bool
latent)

  resolve Context
_ Options
_ QuantityData {value :: QuantityData -> Maybe Double
value = Just Double
value
                         , unit :: QuantityData -> Maybe Unit
unit = Just Unit
unit
                         , aproduct :: QuantityData -> Maybe Text
aproduct = Maybe Text
aproduct
                         , latent :: QuantityData -> Bool
latent = Bool
latent}
   = (QuantityValue, Bool) -> Maybe (QuantityValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> Maybe Text -> QuantityValue
simple Unit
unit Double
value Maybe Text
aproduct, Bool
latent)

  resolve Context
_ Options
_ QuantityData {value :: QuantityData -> Maybe Double
value = Maybe Double
Nothing
                         , unit :: QuantityData -> Maybe Unit
unit = Just Unit
unit
                         , aproduct :: QuantityData -> Maybe Text
aproduct = Maybe Text
aproduct
                         , minValue :: QuantityData -> Maybe Double
minValue = Just Double
from
                         , maxValue :: QuantityData -> Maybe Double
maxValue = Just Double
to
                         , latent :: QuantityData -> Bool
latent = Bool
latent}
   = (QuantityValue, Bool) -> Maybe (QuantityValue, Bool)
forall a. a -> Maybe a
Just (Unit -> (Double, Double) -> Maybe Text -> QuantityValue
between Unit
unit (Double
from, Double
to) Maybe Text
aproduct, Bool
latent)

  resolve Context
_ Options
_ QuantityData {value :: QuantityData -> Maybe Double
value = Maybe Double
Nothing
                         , unit :: QuantityData -> Maybe Unit
unit = Just Unit
unit
                         , aproduct :: QuantityData -> Maybe Text
aproduct = Maybe Text
aproduct
                         , minValue :: QuantityData -> Maybe Double
minValue = Just Double
from
                         , maxValue :: QuantityData -> Maybe Double
maxValue = Maybe Double
Nothing
                         , latent :: QuantityData -> Bool
latent = Bool
latent}
   = (QuantityValue, Bool) -> Maybe (QuantityValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> Maybe Text -> QuantityValue
above Unit
unit Double
from Maybe Text
aproduct, Bool
latent)

  resolve Context
_ Options
_ QuantityData {value :: QuantityData -> Maybe Double
value = Maybe Double
Nothing
                         , unit :: QuantityData -> Maybe Unit
unit = Just Unit
unit
                         , aproduct :: QuantityData -> Maybe Text
aproduct = Maybe Text
aproduct
                         , minValue :: QuantityData -> Maybe Double
minValue = Maybe Double
Nothing
                         , maxValue :: QuantityData -> Maybe Double
maxValue = Just Double
to
                         , latent :: QuantityData -> Bool
latent = Bool
latent}
   = (QuantityValue, Bool) -> Maybe (QuantityValue, Bool)
forall a. a -> Maybe a
Just (Unit -> Double -> Maybe Text -> QuantityValue
under Unit
unit Double
to Maybe Text
aproduct, Bool
latent)

  resolve Context
_ Options
_ QuantityData
_ = Maybe (ResolvedValue QuantityData, Bool)
forall a. Maybe a
Nothing

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 -> Unit
vUnit :: Unit, SingleValue -> Double
vValue :: Double, SingleValue -> Maybe Text
vProduct :: Maybe Text }
    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, (forall x. SingleValue -> Rep SingleValue x)
-> (forall x. Rep SingleValue x -> SingleValue)
-> Generic SingleValue
forall x. Rep SingleValue x -> SingleValue
forall x. SingleValue -> Rep SingleValue x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SingleValue x -> SingleValue
$cfrom :: forall x. SingleValue -> Rep SingleValue x
Generic, Int -> SingleValue -> Int
SingleValue -> Int
(Int -> SingleValue -> Int)
-> (SingleValue -> Int) -> Hashable SingleValue
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: SingleValue -> Int
$chash :: SingleValue -> Int
hashWithSalt :: Int -> SingleValue -> Int
$chashWithSalt :: Int -> SingleValue -> Int
Hashable, Eq SingleValue
Eq SingleValue
-> (SingleValue -> SingleValue -> Ordering)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> Bool)
-> (SingleValue -> SingleValue -> SingleValue)
-> (SingleValue -> SingleValue -> SingleValue)
-> Ord SingleValue
SingleValue -> SingleValue -> Bool
SingleValue -> SingleValue -> Ordering
SingleValue -> SingleValue -> SingleValue
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 :: SingleValue -> SingleValue -> SingleValue
$cmin :: SingleValue -> SingleValue -> SingleValue
max :: SingleValue -> SingleValue -> SingleValue
$cmax :: SingleValue -> SingleValue -> SingleValue
>= :: SingleValue -> SingleValue -> Bool
$c>= :: SingleValue -> SingleValue -> Bool
> :: SingleValue -> SingleValue -> Bool
$c> :: SingleValue -> SingleValue -> Bool
<= :: SingleValue -> SingleValue -> Bool
$c<= :: SingleValue -> SingleValue -> Bool
< :: SingleValue -> SingleValue -> Bool
$c< :: SingleValue -> SingleValue -> Bool
compare :: SingleValue -> SingleValue -> Ordering
$ccompare :: SingleValue -> SingleValue -> Ordering
$cp1Ord :: Eq SingleValue
Ord, 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, SingleValue -> ()
(SingleValue -> ()) -> NFData SingleValue
forall a. (a -> ()) -> NFData a
rnf :: SingleValue -> ()
$crnf :: SingleValue -> ()
NFData)

instance ToJSON SingleValue where
    toJSON :: SingleValue -> Value
toJSON (SingleValue Unit
unit Double
value Maybe Text
aproduct) = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
      [ Text
"value" Text -> Double -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Double
value
      , Text
"unit" Text -> Unit -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Unit
unit
      ]
      [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [ Text
"product" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Text
p | Just Text
p <- [Maybe Text
aproduct] ]

data QuantityValue
  = SimpleValue SingleValue
  | IntervalValue (SingleValue, SingleValue)
  | OpenIntervalValue (SingleValue, IntervalDirection)
  deriving (QuantityValue -> QuantityValue -> Bool
(QuantityValue -> QuantityValue -> Bool)
-> (QuantityValue -> QuantityValue -> Bool) -> Eq QuantityValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: QuantityValue -> QuantityValue -> Bool
$c/= :: QuantityValue -> QuantityValue -> Bool
== :: QuantityValue -> QuantityValue -> Bool
$c== :: QuantityValue -> QuantityValue -> Bool
Eq, Eq QuantityValue
Eq QuantityValue
-> (QuantityValue -> QuantityValue -> Ordering)
-> (QuantityValue -> QuantityValue -> Bool)
-> (QuantityValue -> QuantityValue -> Bool)
-> (QuantityValue -> QuantityValue -> Bool)
-> (QuantityValue -> QuantityValue -> Bool)
-> (QuantityValue -> QuantityValue -> QuantityValue)
-> (QuantityValue -> QuantityValue -> QuantityValue)
-> Ord QuantityValue
QuantityValue -> QuantityValue -> Bool
QuantityValue -> QuantityValue -> Ordering
QuantityValue -> QuantityValue -> QuantityValue
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 :: QuantityValue -> QuantityValue -> QuantityValue
$cmin :: QuantityValue -> QuantityValue -> QuantityValue
max :: QuantityValue -> QuantityValue -> QuantityValue
$cmax :: QuantityValue -> QuantityValue -> QuantityValue
>= :: QuantityValue -> QuantityValue -> Bool
$c>= :: QuantityValue -> QuantityValue -> Bool
> :: QuantityValue -> QuantityValue -> Bool
$c> :: QuantityValue -> QuantityValue -> Bool
<= :: QuantityValue -> QuantityValue -> Bool
$c<= :: QuantityValue -> QuantityValue -> Bool
< :: QuantityValue -> QuantityValue -> Bool
$c< :: QuantityValue -> QuantityValue -> Bool
compare :: QuantityValue -> QuantityValue -> Ordering
$ccompare :: QuantityValue -> QuantityValue -> Ordering
$cp1Ord :: Eq QuantityValue
Ord, Int -> QuantityValue -> ShowS
[QuantityValue] -> ShowS
QuantityValue -> String
(Int -> QuantityValue -> ShowS)
-> (QuantityValue -> String)
-> ([QuantityValue] -> ShowS)
-> Show QuantityValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [QuantityValue] -> ShowS
$cshowList :: [QuantityValue] -> ShowS
show :: QuantityValue -> String
$cshow :: QuantityValue -> String
showsPrec :: Int -> QuantityValue -> ShowS
$cshowsPrec :: Int -> QuantityValue -> ShowS
Show)

instance ToJSON QuantityValue where
  toJSON :: QuantityValue -> 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 :: Unit -> Double -> Maybe Text -> QuantityValue
simple :: Unit -> Double -> Maybe Text -> QuantityValue
simple Unit
u Double
v Maybe Text
p = SingleValue -> QuantityValue
SimpleValue (SingleValue -> QuantityValue) -> SingleValue -> QuantityValue
forall a b. (a -> b) -> a -> b
$ Unit -> Double -> Maybe Text -> SingleValue
single Unit
u Double
v Maybe Text
p

between :: Unit -> (Double, Double) -> Maybe Text -> QuantityValue
between :: Unit -> (Double, Double) -> Maybe Text -> QuantityValue
between Unit
u (Double
from, Double
to) Maybe Text
p = (SingleValue, SingleValue) -> QuantityValue
IntervalValue (Unit -> Double -> Maybe Text -> SingleValue
single Unit
u Double
from Maybe Text
p, Unit -> Double -> Maybe Text -> SingleValue
single Unit
u Double
to Maybe Text
p)

above :: Unit -> Double -> Maybe Text -> QuantityValue
above :: Unit -> Double -> Maybe Text -> QuantityValue
above = IntervalDirection -> Unit -> Double -> Maybe Text -> QuantityValue
openInterval IntervalDirection
Above

under :: Unit -> Double -> Maybe Text -> QuantityValue
under :: Unit -> Double -> Maybe Text -> QuantityValue
under = IntervalDirection -> Unit -> Double -> Maybe Text -> QuantityValue
openInterval IntervalDirection
Under

openInterval
  :: IntervalDirection -> Unit -> Double -> Maybe Text -> QuantityValue
openInterval :: IntervalDirection -> Unit -> Double -> Maybe Text -> QuantityValue
openInterval IntervalDirection
direction Unit
u Double
v Maybe Text
p = (SingleValue, IntervalDirection) -> QuantityValue
OpenIntervalValue (Unit -> Double -> Maybe Text -> SingleValue
single Unit
u Double
v Maybe Text
p, IntervalDirection
direction)

single :: Unit -> Double -> Maybe Text -> SingleValue
single :: Unit -> Double -> Maybe Text -> SingleValue
single Unit
u Double
v Maybe Text
p = SingleValue :: Unit -> Double -> Maybe Text -> SingleValue
SingleValue {vUnit :: Unit
vUnit = Unit
u, vValue :: Double
vValue = Double
v, vProduct :: Maybe Text
vProduct = Maybe Text
p}