aeson-decode-0.1.0.1: test/Examples/Policy.hs
module Examples.Policy (spec) where
import AesonDecode
import Essentials
import Control.Applicative (optional)
import Data.Aeson (Value)
import Data.Aeson.QQ (aesonQQ)
import Data.Text (Text)
import Data.Time.Clock.POSIX (POSIXTime)
import Prelude (fromInteger)
import Test.Hspec (it, shouldBe, Spec)
newtype Resource = Resource Text deriving (Eq, Show)
data StartTime = StartImmediately | StartTime POSIXTime deriving (Eq, Show)
newtype EndTime = EndTime POSIXTime deriving (Eq, Show)
data IpAddress = AnyIp | IpAddress Text deriving (Eq, Show)
data Policy = Policy
{ policyResource :: Resource
, policyStart :: StartTime
, policyEnd :: EndTime
, policyIpAddress :: IpAddress
}
deriving (Eq, Show)
spec :: Spec
spec = it "policy example" $ (json ^? d) `shouldBe` Just p
json :: Value
json =
[aesonQQ|
{
"Statement": [
{
"Resource": "http://d111111abcdef8.cloudfront.net/game_download.zip",
"Condition": {
"IpAddress": {"AWS:SourceIp": "192.0.2.0/24"},
"DateLessThan": {"AWS:EpochTime": 1357034400}
}
}
]
}
|]
d'time :: Decoder POSIXTime
d'time :: Decoder POSIXTime = at "AWS:EpochTime" integer <&> fromInteger
d :: Decoder Policy
d :: Decoder Policy = at ("Statement" <> only) $ do
res <- Resource <$> at "Resource" text
start <- maybe StartImmediately StartTime <$>
(optional $ at ("Condition" <> "DateGreaterThan") d'time)
end <- EndTime <$> at ("Condition" <> "DateLessThan") d'time
ip <- maybe AnyIp IpAddress <$>
(optional $ at ("Condition" <> "IpAddress")
(at "AWS:SourceIp" text))
pure $ Policy res start end ip
p :: Policy
p = Policy
(Resource "http://d111111abcdef8.cloudfront.net/game_download.zip")
StartImmediately
(EndTime 1357034400)
(IpAddress "192.0.2.0/24")