Skip to content

Commit

Permalink
main:CollectionResource consists of CollectionItem s
Browse files Browse the repository at this point in the history
  • Loading branch information
bruderj15 committed Oct 27, 2024
1 parent c5aa0d6 commit e282cb5
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/Servant/Hateoas/ContentType/Collection.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,35 @@ data Collection (t :: Type)
-- | Resource wrapper for Collection.
data CollectionResource a = CollectionResource
{ href :: Maybe String
, items :: [a]
, items :: [CollectionItem a]
, links :: [(String, Link)]
} deriving (Generic)
} deriving (Show, Generic)

-- | A single item inside a 'CollectionResource'.
data CollectionItem a = CollectionItem
{ item :: a
, itemLinks :: [(String, Link)]
} deriving (Show, Generic)

instance HasResource (Collection t) where
type Resource (Collection t) = CollectionResource

instance Accept (Collection JSON) where
contentType _ = "application" M.// "vnd.collection+json"

instance ToJSON a => ToJSON (CollectionItem a) where
toJSON (CollectionItem (toJSON -> Object m) ls) = object ["data" .= itemData, "links" .= collectionLinks ls]
where
itemData = Array $ Foldable.foldl' (\xs (k, v) -> pure (object ["name" .= k, "value" .= v]) <> xs) mempty $ toList m
toJSON (CollectionItem (toJSON -> v) _) = v

instance {-# OVERLAPPABLE #-} ToJSON a => ToJSON (CollectionResource a) where
toJSON (CollectionResource mHref is ls) = object ["collection".= collection]
where
collection = object $ ["version" .= ("1.0" :: String), "links" .= ls', "items" .= is'] <> maybe [] (pure . ("href" .=)) mHref
ls' = Array $ Foldable.foldl' (\xs (rel, l) -> pure (object ["name" .= rel, "value" .= linkURI l]) <> xs) mempty ls
is' = Array $ Foldable.foldl' (\xs i -> pure (object ["data" .= toCollectionData i, "links" .= (mempty :: Array)]) <> xs) mempty is
collection = object $ ["version" .= ("1.0" :: String), "links" .= collectionLinks ls, "items" .= is'] <> maybe [] (pure . ("href" .=)) mHref
is' = Array $ Foldable.foldl' (\xs i -> pure (toJSON i) <> xs) mempty is

collectionLinks :: [(String, Link)] -> Value
collectionLinks = Array . Foldable.foldl' (\xs (rel, l) -> pure (object ["name" .= rel, "value" .= linkURI l]) <> xs) mempty

toCollectionData :: ToJSON a => a -> Value
toCollectionData (toJSON -> Object m) = Array $ Foldable.foldl' (\xs (k, v) -> pure (object ["name" .= k, "value" .= v]) <> xs) mempty $ toList m
toCollectionData (toJSON -> x) = x
-- instance ToResource ... - both for CollectionItem and CollectionResource...?

0 comments on commit e282cb5

Please sign in to comment.