Skip to content

Instantly share code, notes, and snippets.

@kofno
Last active January 26, 2016 23:03
Show Gist options
  • Save kofno/3d104c0bdedb23cd98fb to your computer and use it in GitHub Desktop.
Save kofno/3d104c0bdedb23cd98fb to your computer and use it in GitHub Desktop.
Parsing AWS JSON w/ Purescript

Paring AWS JSON w/ PureScript

I'm experimenting with parsing AWS JSON with purescript.

Given the Data.JSON.S3 module provided, here's what I see in the console:

$> eitherDecode "{ \"Records\": [{ \"s3\": { \"bucket\": { \"name\": \"foo\"}, \"object\": { \"key\": \"bar.png\" } } } ] }" :: Either String Records

Left ("fromList Cons (Tuple (\"s3\") (JObject fromList Cons (Tuple (\"bucket\") (JObject fromList Cons (Tuple (\"name\") (JString \"foo\")) (Nil))) (Cons (Tuple (\"object\") (JObject fromList Cons (Tuple (\"key\") (JString \"bar.png\")) (Nil))) (Nil)))) (Nil) is not (Either a b).")

Parsing the individual S3 objects works as expected. Why doesn't this work?

{
"Records": [
{
"s3": {
"bucket": { "name": "foo"},
"object": { "key": "bar.png" }
}
}
]
}
module Data.JSON.S3 where
import Prelude
import Data.Maybe
import Data.Either
import Data.Array
import Data.JSON
data Records = Records (Array (Either String S3))
data S3 = S3 S3Children
data S3Children = S3Children Bucket S3Object
data Bucket = Bucket String
data S3Object = S3Object String
instance showS3 :: Show S3 where
show (S3 x) =
"S3 " ++ show x
instance showS3Children :: Show S3Children where
show (S3Children b o) =
"S3Children " ++ show b ++ " " ++ show o
instance showBucket :: Show Bucket where
show (Bucket s) = "Bucket " ++ s
instance showS3Object :: Show S3Object where
show (S3Object s) = "S3Object " ++ s
instance showRecords :: Show Records where
show (Records xs) = "Records " ++ show xs
instance recordsFromJSON :: FromJSON Records where
parseJSON (JObject o) = Records <$> (o .: "Records")
parseJSON _ = fail "Records parse failed"
instance s3FromJSON :: FromJSON S3 where
parseJSON (JObject o) = S3 <$> (o .: "s3")
parseJSON _ = fail "S3 parse failed"
instance s3ChildrenFromJSON :: FromJSON S3Children where
parseJSON (JObject o) = S3Children <$> (o .: "bucket") <*> (o .: "object")
parseJSON _ = fail "S3Children parse failed"
instance bucketFromJSON :: FromJSON Bucket where
parseJSON (JObject o) = Bucket <$> (o .: "name")
parseJSON _ = fail "Bucket parse failed"
instance s3ObjectFromJSON :: FromJSON S3Object where
parseJSON (JObject o) = S3Object <$> (o .: "key")
parseJSON _ = fail "S3Object parse failed"
@kofno
Copy link
Author

kofno commented Oct 5, 2015

IRC sorted me out. Instead of data Records = Records (Array (Either String S3)) I just needed data Records = Records (Array S3)

I feel like I'm still working too hard though... so I'll probably come back to this...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment