module Hydra.Node.DepositPeriod where

import Hydra.Prelude

import Test.QuickCheck (choose)

-- | A new type wrapped period of time to be used in deposit validity.
newtype DepositPeriod = DepositPeriod {DepositPeriod -> NominalDiffTime
toNominalDiffTime :: NominalDiffTime}
  deriving stock (DepositPeriod -> DepositPeriod -> Bool
(DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool) -> Eq DepositPeriod
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DepositPeriod -> DepositPeriod -> Bool
== :: DepositPeriod -> DepositPeriod -> Bool
$c/= :: DepositPeriod -> DepositPeriod -> Bool
/= :: DepositPeriod -> DepositPeriod -> Bool
Eq, Eq DepositPeriod
Eq DepositPeriod =>
(DepositPeriod -> DepositPeriod -> Ordering)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> Bool)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> Ord DepositPeriod
DepositPeriod -> DepositPeriod -> Bool
DepositPeriod -> DepositPeriod -> Ordering
DepositPeriod -> DepositPeriod -> DepositPeriod
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
$ccompare :: DepositPeriod -> DepositPeriod -> Ordering
compare :: DepositPeriod -> DepositPeriod -> Ordering
$c< :: DepositPeriod -> DepositPeriod -> Bool
< :: DepositPeriod -> DepositPeriod -> Bool
$c<= :: DepositPeriod -> DepositPeriod -> Bool
<= :: DepositPeriod -> DepositPeriod -> Bool
$c> :: DepositPeriod -> DepositPeriod -> Bool
> :: DepositPeriod -> DepositPeriod -> Bool
$c>= :: DepositPeriod -> DepositPeriod -> Bool
>= :: DepositPeriod -> DepositPeriod -> Bool
$cmax :: DepositPeriod -> DepositPeriod -> DepositPeriod
max :: DepositPeriod -> DepositPeriod -> DepositPeriod
$cmin :: DepositPeriod -> DepositPeriod -> DepositPeriod
min :: DepositPeriod -> DepositPeriod -> DepositPeriod
Ord)
  deriving newtype (Int -> DepositPeriod -> ShowS
[DepositPeriod] -> ShowS
DepositPeriod -> String
(Int -> DepositPeriod -> ShowS)
-> (DepositPeriod -> String)
-> ([DepositPeriod] -> ShowS)
-> Show DepositPeriod
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DepositPeriod -> ShowS
showsPrec :: Int -> DepositPeriod -> ShowS
$cshow :: DepositPeriod -> String
show :: DepositPeriod -> String
$cshowList :: [DepositPeriod] -> ShowS
showList :: [DepositPeriod] -> ShowS
Show, ReadPrec [DepositPeriod]
ReadPrec DepositPeriod
Int -> ReadS DepositPeriod
ReadS [DepositPeriod]
(Int -> ReadS DepositPeriod)
-> ReadS [DepositPeriod]
-> ReadPrec DepositPeriod
-> ReadPrec [DepositPeriod]
-> Read DepositPeriod
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DepositPeriod
readsPrec :: Int -> ReadS DepositPeriod
$creadList :: ReadS [DepositPeriod]
readList :: ReadS [DepositPeriod]
$creadPrec :: ReadPrec DepositPeriod
readPrec :: ReadPrec DepositPeriod
$creadListPrec :: ReadPrec [DepositPeriod]
readListPrec :: ReadPrec [DepositPeriod]
Read, Integer -> DepositPeriod
DepositPeriod -> DepositPeriod
DepositPeriod -> DepositPeriod -> DepositPeriod
(DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (Integer -> DepositPeriod)
-> Num DepositPeriod
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: DepositPeriod -> DepositPeriod -> DepositPeriod
+ :: DepositPeriod -> DepositPeriod -> DepositPeriod
$c- :: DepositPeriod -> DepositPeriod -> DepositPeriod
- :: DepositPeriod -> DepositPeriod -> DepositPeriod
$c* :: DepositPeriod -> DepositPeriod -> DepositPeriod
* :: DepositPeriod -> DepositPeriod -> DepositPeriod
$cnegate :: DepositPeriod -> DepositPeriod
negate :: DepositPeriod -> DepositPeriod
$cabs :: DepositPeriod -> DepositPeriod
abs :: DepositPeriod -> DepositPeriod
$csignum :: DepositPeriod -> DepositPeriod
signum :: DepositPeriod -> DepositPeriod
$cfromInteger :: Integer -> DepositPeriod
fromInteger :: Integer -> DepositPeriod
Num, Int -> DepositPeriod
DepositPeriod -> Int
DepositPeriod -> [DepositPeriod]
DepositPeriod -> DepositPeriod
DepositPeriod -> DepositPeriod -> [DepositPeriod]
DepositPeriod -> DepositPeriod -> DepositPeriod -> [DepositPeriod]
(DepositPeriod -> DepositPeriod)
-> (DepositPeriod -> DepositPeriod)
-> (Int -> DepositPeriod)
-> (DepositPeriod -> Int)
-> (DepositPeriod -> [DepositPeriod])
-> (DepositPeriod -> DepositPeriod -> [DepositPeriod])
-> (DepositPeriod -> DepositPeriod -> [DepositPeriod])
-> (DepositPeriod
    -> DepositPeriod -> DepositPeriod -> [DepositPeriod])
-> Enum DepositPeriod
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: DepositPeriod -> DepositPeriod
succ :: DepositPeriod -> DepositPeriod
$cpred :: DepositPeriod -> DepositPeriod
pred :: DepositPeriod -> DepositPeriod
$ctoEnum :: Int -> DepositPeriod
toEnum :: Int -> DepositPeriod
$cfromEnum :: DepositPeriod -> Int
fromEnum :: DepositPeriod -> Int
$cenumFrom :: DepositPeriod -> [DepositPeriod]
enumFrom :: DepositPeriod -> [DepositPeriod]
$cenumFromThen :: DepositPeriod -> DepositPeriod -> [DepositPeriod]
enumFromThen :: DepositPeriod -> DepositPeriod -> [DepositPeriod]
$cenumFromTo :: DepositPeriod -> DepositPeriod -> [DepositPeriod]
enumFromTo :: DepositPeriod -> DepositPeriod -> [DepositPeriod]
$cenumFromThenTo :: DepositPeriod -> DepositPeriod -> DepositPeriod -> [DepositPeriod]
enumFromThenTo :: DepositPeriod -> DepositPeriod -> DepositPeriod -> [DepositPeriod]
Enum, Num DepositPeriod
Ord DepositPeriod
(Num DepositPeriod, Ord DepositPeriod) =>
(DepositPeriod -> Rational) -> Real DepositPeriod
DepositPeriod -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
$ctoRational :: DepositPeriod -> Rational
toRational :: DepositPeriod -> Rational
Real, [DepositPeriod] -> Value
[DepositPeriod] -> Encoding
DepositPeriod -> Bool
DepositPeriod -> Value
DepositPeriod -> Encoding
(DepositPeriod -> Value)
-> (DepositPeriod -> Encoding)
-> ([DepositPeriod] -> Value)
-> ([DepositPeriod] -> Encoding)
-> (DepositPeriod -> Bool)
-> ToJSON DepositPeriod
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
$ctoJSON :: DepositPeriod -> Value
toJSON :: DepositPeriod -> Value
$ctoEncoding :: DepositPeriod -> Encoding
toEncoding :: DepositPeriod -> Encoding
$ctoJSONList :: [DepositPeriod] -> Value
toJSONList :: [DepositPeriod] -> Value
$ctoEncodingList :: [DepositPeriod] -> Encoding
toEncodingList :: [DepositPeriod] -> Encoding
$comitField :: DepositPeriod -> Bool
omitField :: DepositPeriod -> Bool
ToJSON, Maybe DepositPeriod
Value -> Parser [DepositPeriod]
Value -> Parser DepositPeriod
(Value -> Parser DepositPeriod)
-> (Value -> Parser [DepositPeriod])
-> Maybe DepositPeriod
-> FromJSON DepositPeriod
forall a.
(Value -> Parser a)
-> (Value -> Parser [a]) -> Maybe a -> FromJSON a
$cparseJSON :: Value -> Parser DepositPeriod
parseJSON :: Value -> Parser DepositPeriod
$cparseJSONList :: Value -> Parser [DepositPeriod]
parseJSONList :: Value -> Parser [DepositPeriod]
$comittedField :: Maybe DepositPeriod
omittedField :: Maybe DepositPeriod
FromJSON)

-- | Truncates to whole seconds.
instance Integral DepositPeriod where
  quotRem :: DepositPeriod -> DepositPeriod -> (DepositPeriod, DepositPeriod)
quotRem (DepositPeriod NominalDiffTime
a) (DepositPeriod NominalDiffTime
b) = (NominalDiffTime -> DepositPeriod
DepositPeriod (NominalDiffTime -> DepositPeriod)
-> NominalDiffTime -> DepositPeriod
forall a b. (a -> b) -> a -> b
$ Integer -> NominalDiffTime
forall a. Num a => Integer -> a
fromInteger Integer
q, NominalDiffTime -> DepositPeriod
DepositPeriod NominalDiffTime
r)
   where
    (Integer
q, NominalDiffTime
r) = NominalDiffTime -> (Integer, NominalDiffTime)
forall b. Integral b => NominalDiffTime -> (b, NominalDiffTime)
forall a b. (RealFrac a, Integral b) => a -> (b, a)
properFraction (NominalDiffTime
a NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Fractional a => a -> a -> a
/ NominalDiffTime
b)

  toInteger :: DepositPeriod -> Integer
toInteger (DepositPeriod NominalDiffTime
a) = NominalDiffTime -> Integer
forall b. Integral b => NominalDiffTime -> b
forall a b. (RealFrac a, Integral b) => a -> b
round NominalDiffTime
a

instance Arbitrary DepositPeriod where
  arbitrary :: Gen DepositPeriod
arbitrary = NominalDiffTime -> DepositPeriod
DepositPeriod (NominalDiffTime -> DepositPeriod)
-> (Integer -> NominalDiffTime) -> Integer -> DepositPeriod
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> NominalDiffTime
forall a. Num a => Integer -> a
fromInteger (Integer -> DepositPeriod) -> Gen Integer -> Gen DepositPeriod
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer, Integer) -> Gen Integer
forall a. Random a => (a, a) -> Gen a
choose (Integer
1, Integer
86400)