module Data.CollectionJSON where
import Data.Aeson ((.=), (.:?), (.!=), (.:), FromJSON (parseJSON), object, ToJSON (toJSON), withObject)
import Data.Functor ((<$>))
import Data.Maybe (catMaybes)
import Data.Text (Text)
import Network.URI (nullURI, URI)
import External.Network.URI.JSON ()
data Collection = Collection
{ cVersion :: Text
, cHref :: URI
, cLinks :: [Link]
, cItems :: [Item]
, cQueries :: [Query]
, cTemplate :: Maybe Template
, cError :: Maybe Error
} deriving (Eq, Show)
instance FromJSON Collection where
parseJSON = withObject "Collection" $ \ c -> do
v <- c .: "collection"
cVersion <- v .:? "version" .!= "1.0"
cHref <- v .:? "href" .!= nullURI
cLinks <- v .:? "links" .!= []
cItems <- v .:? "items" .!= []
cQueries <- v .:? "queries" .!= []
cTemplate <- v .:? "template"
cError <- v .:? "error"
return Collection{..}
instance ToJSON Collection where
toJSON Collection{..} = object
[ "collection" .= object (catMaybes
[ Just $ "version" .= cVersion
, Just $ "href" .= cHref
, if null cLinks then Nothing else Just $ "links" .= cLinks
, if null cItems then Nothing else Just $ "items" .= cItems
, if null cQueries then Nothing else Just $ "queries" .= cQueries
, (.=) "template" <$> cTemplate
, (.=) "error" <$> cError
]
) ]
data Link = Link
{ lHref :: URI
, lRel :: Text
, lName :: Maybe Text
, lRender :: Maybe Text
, lPrompt :: Maybe Text
} deriving (Eq, Show)
instance FromJSON Link where
parseJSON = withObject "Link" $ \ v -> do
lHref <- v .: "href"
lRel <- v .: "rel"
lName <- v .:? "name"
lRender <- v .:? "render"
lPrompt <- v .:? "prompt"
return Link{..}
instance ToJSON Link where
toJSON Link{..} = object $ catMaybes
[ Just $ "href" .= lHref
, Just $ "rel" .= lRel
, (.=) "name" <$> lName
, (.=) "render" <$> lRender
, (.=) "prompt" <$> lPrompt
]
data Item = Item
{ iHref :: URI
, iData :: [Datum]
, iLinks :: [Link]
} deriving (Eq, Show)
instance FromJSON Item where
parseJSON = withObject "Item" $ \ v -> do
iHref <- v .: "href"
iData <- v .:? "data" .!= []
iLinks <- v .:? "links" .!= []
return Item{..}
instance ToJSON Item where
toJSON Item{..} = object $ catMaybes
[ Just $ "href" .= iHref
, if null iData then Nothing else Just $ "data" .= iData
, if null iLinks then Nothing else Just $ "links" .= iLinks
]
data Query = Query
{ qHref :: URI
, qRel :: Text
, qName :: Maybe Text
, qPrompt :: Maybe Text
, qData :: [Datum]
} deriving (Eq, Show)
instance FromJSON Query where
parseJSON = withObject "Query" $ \ v -> do
qHref <- v .: "href"
qRel <- v .: "rel"
qName <- v .:? "name"
qPrompt <- v .:? "prompt"
qData <- v .:? "data" .!= []
return Query{..}
instance ToJSON Query where
toJSON Query{..} = object $ catMaybes
[ Just $ "href" .= qHref
, Just $ "rel" .= qRel
, (.=) "name" <$> qName
, (.=) "prompt" <$> qPrompt
, if null qData then Nothing else Just $ "data" .= qData
]
newtype Template = Template
{ tData :: [Datum]
} deriving (Eq, Show)
instance FromJSON Template where
parseJSON = withObject "Template" $ \ v -> do
tData <- v .:? "data" .!= []
return Template{..}
instance ToJSON Template where
toJSON Template{..} = object
[ "data" .= tData
]
data Error = Error
{ eTitle :: Maybe Text
, eCode :: Maybe Text
, eMessage :: Maybe Text
} deriving (Eq, Show)
instance FromJSON Error where
parseJSON = withObject "Error" $ \ v -> do
eTitle <- v .:? "title"
eCode <- v .:? "code"
eMessage <- v .:? "message"
return Error{..}
instance ToJSON Error where
toJSON Error{..} = object $ catMaybes
[ (.=) "title" <$> eTitle
, (.=) "code" <$> eCode
, (.=) "message" <$> eMessage
]
data Datum = Datum
{ dName :: Text
, dValue :: Maybe Text
, dPrompt :: Maybe Text
} deriving (Eq, Show)
instance FromJSON Datum where
parseJSON = withObject "Datum" $ \ v -> do
dName <- v .: "name"
dValue <- v .:? "value"
dPrompt <- v .:? "prompt"
return Datum{..}
instance ToJSON Datum where
toJSON Datum{..} = object $ catMaybes
[ Just $ "name" .= dName
, (.=) "value" <$> dValue
, (.=) "prompt" <$> dPrompt
]
class FromCollection a where
fromCollection :: Collection -> a
class ToCollection a where
toCollection :: a -> Collection