packages feed

collection-json 0.1.0.0 → 1.0.0.0

raw patch · 10 files changed

+560/−206 lines, 10 filesdep +QuickCheckdep +network-uridep +quickcheck-instancesdep −bytestringdep ~aesondep ~basedep ~textnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, network-uri, quickcheck-instances, test-invariant

Dependencies removed: bytestring

Dependency ranges changed: aeson, base, text

API changes (from Hackage documentation)

- Text.JSON.CollectionJSON.Types: Collection :: Text -> Text -> [Link] -> [Item] -> [Query] -> Maybe Template -> Maybe Error -> Collection
- Text.JSON.CollectionJSON.Types: Data :: Text -> Maybe Text -> Maybe Text -> Data
- Text.JSON.CollectionJSON.Types: Error :: Text -> Maybe Text -> Maybe Text -> Error
- Text.JSON.CollectionJSON.Types: Item :: Text -> [Data] -> [Link] -> Item
- Text.JSON.CollectionJSON.Types: Link :: Text -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> Link
- Text.JSON.CollectionJSON.Types: Query :: Text -> Text -> Maybe Text -> Maybe Text -> [Data] -> Query
- Text.JSON.CollectionJSON.Types: Template :: [Data] -> Template
- Text.JSON.CollectionJSON.Types: cError :: Collection -> Maybe Error
- Text.JSON.CollectionJSON.Types: cHref :: Collection -> Text
- Text.JSON.CollectionJSON.Types: cItems :: Collection -> [Item]
- Text.JSON.CollectionJSON.Types: cLinks :: Collection -> [Link]
- Text.JSON.CollectionJSON.Types: cQueries :: Collection -> [Query]
- Text.JSON.CollectionJSON.Types: cTemplate :: Collection -> Maybe Template
- Text.JSON.CollectionJSON.Types: cVersion :: Collection -> Text
- Text.JSON.CollectionJSON.Types: dName :: Data -> Text
- Text.JSON.CollectionJSON.Types: dPrompt :: Data -> Maybe Text
- Text.JSON.CollectionJSON.Types: dValue :: Data -> Maybe Text
- Text.JSON.CollectionJSON.Types: data Collection
- Text.JSON.CollectionJSON.Types: data Data
- Text.JSON.CollectionJSON.Types: data Error
- Text.JSON.CollectionJSON.Types: data Item
- Text.JSON.CollectionJSON.Types: data Link
- Text.JSON.CollectionJSON.Types: data Query
- Text.JSON.CollectionJSON.Types: data Template
- Text.JSON.CollectionJSON.Types: eCode :: Error -> Maybe Text
- Text.JSON.CollectionJSON.Types: eMessage :: Error -> Maybe Text
- Text.JSON.CollectionJSON.Types: eTitle :: Error -> Text
- Text.JSON.CollectionJSON.Types: iData :: Item -> [Data]
- Text.JSON.CollectionJSON.Types: iHref :: Item -> Text
- Text.JSON.CollectionJSON.Types: iLinks :: Item -> [Link]
- Text.JSON.CollectionJSON.Types: instance FromJSON Collection
- Text.JSON.CollectionJSON.Types: instance FromJSON Data
- Text.JSON.CollectionJSON.Types: instance FromJSON Error
- Text.JSON.CollectionJSON.Types: instance FromJSON Item
- Text.JSON.CollectionJSON.Types: instance FromJSON Link
- Text.JSON.CollectionJSON.Types: instance FromJSON Query
- Text.JSON.CollectionJSON.Types: instance FromJSON Template
- Text.JSON.CollectionJSON.Types: instance Show Collection
- Text.JSON.CollectionJSON.Types: instance Show Data
- Text.JSON.CollectionJSON.Types: instance Show Error
- Text.JSON.CollectionJSON.Types: instance Show Item
- Text.JSON.CollectionJSON.Types: instance Show Link
- Text.JSON.CollectionJSON.Types: instance Show Query
- Text.JSON.CollectionJSON.Types: instance Show Template
- Text.JSON.CollectionJSON.Types: instance ToJSON Collection
- Text.JSON.CollectionJSON.Types: instance ToJSON Data
- Text.JSON.CollectionJSON.Types: instance ToJSON Error
- Text.JSON.CollectionJSON.Types: instance ToJSON Item
- Text.JSON.CollectionJSON.Types: instance ToJSON Link
- Text.JSON.CollectionJSON.Types: instance ToJSON Query
- Text.JSON.CollectionJSON.Types: instance ToJSON Template
- Text.JSON.CollectionJSON.Types: lHref :: Link -> Text
- Text.JSON.CollectionJSON.Types: lName :: Link -> Maybe Text
- Text.JSON.CollectionJSON.Types: lPrompt :: Link -> Maybe Text
- Text.JSON.CollectionJSON.Types: lRel :: Link -> Text
- Text.JSON.CollectionJSON.Types: lRender :: Link -> Maybe Text
- Text.JSON.CollectionJSON.Types: qData :: Query -> [Data]
- Text.JSON.CollectionJSON.Types: qHref :: Query -> Text
- Text.JSON.CollectionJSON.Types: qName :: Query -> Maybe Text
- Text.JSON.CollectionJSON.Types: qPrompt :: Query -> Maybe Text
- Text.JSON.CollectionJSON.Types: qRel :: Query -> Text
- Text.JSON.CollectionJSON.Types: tData :: Template -> [Data]
+ Data.CollectionJSON: Collection :: Text -> URI -> [Link] -> [Item] -> [Query] -> Maybe Template -> Maybe Error -> Collection
+ Data.CollectionJSON: Datum :: Text -> Maybe Text -> Maybe Text -> Datum
+ Data.CollectionJSON: Error :: Maybe Text -> Maybe Text -> Maybe Text -> Error
+ Data.CollectionJSON: Item :: URI -> [Datum] -> [Link] -> Item
+ Data.CollectionJSON: Link :: URI -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> Link
+ Data.CollectionJSON: Query :: URI -> Text -> Maybe Text -> Maybe Text -> [Datum] -> Query
+ Data.CollectionJSON: Template :: [Datum] -> Template
+ Data.CollectionJSON: [cError] :: Collection -> Maybe Error
+ Data.CollectionJSON: [cHref] :: Collection -> URI
+ Data.CollectionJSON: [cItems] :: Collection -> [Item]
+ Data.CollectionJSON: [cLinks] :: Collection -> [Link]
+ Data.CollectionJSON: [cQueries] :: Collection -> [Query]
+ Data.CollectionJSON: [cTemplate] :: Collection -> Maybe Template
+ Data.CollectionJSON: [cVersion] :: Collection -> Text
+ Data.CollectionJSON: [dName] :: Datum -> Text
+ Data.CollectionJSON: [dPrompt] :: Datum -> Maybe Text
+ Data.CollectionJSON: [dValue] :: Datum -> Maybe Text
+ Data.CollectionJSON: [eCode] :: Error -> Maybe Text
+ Data.CollectionJSON: [eMessage] :: Error -> Maybe Text
+ Data.CollectionJSON: [eTitle] :: Error -> Maybe Text
+ Data.CollectionJSON: [iData] :: Item -> [Datum]
+ Data.CollectionJSON: [iHref] :: Item -> URI
+ Data.CollectionJSON: [iLinks] :: Item -> [Link]
+ Data.CollectionJSON: [lHref] :: Link -> URI
+ Data.CollectionJSON: [lName] :: Link -> Maybe Text
+ Data.CollectionJSON: [lPrompt] :: Link -> Maybe Text
+ Data.CollectionJSON: [lRel] :: Link -> Text
+ Data.CollectionJSON: [lRender] :: Link -> Maybe Text
+ Data.CollectionJSON: [qData] :: Query -> [Datum]
+ Data.CollectionJSON: [qHref] :: Query -> URI
+ Data.CollectionJSON: [qName] :: Query -> Maybe Text
+ Data.CollectionJSON: [qPrompt] :: Query -> Maybe Text
+ Data.CollectionJSON: [qRel] :: Query -> Text
+ Data.CollectionJSON: [tData] :: Template -> [Datum]
+ Data.CollectionJSON: class FromCollection a
+ Data.CollectionJSON: class ToCollection a
+ Data.CollectionJSON: data Collection
+ Data.CollectionJSON: data Datum
+ Data.CollectionJSON: data Error
+ Data.CollectionJSON: data Item
+ Data.CollectionJSON: data Link
+ Data.CollectionJSON: data Query
+ Data.CollectionJSON: fromCollection :: FromCollection a => Collection -> a
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Collection
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Datum
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Error
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Item
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Link
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Query
+ Data.CollectionJSON: instance Data.Aeson.Types.FromJSON.FromJSON Data.CollectionJSON.Template
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Collection
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Datum
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Error
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Item
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Link
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Query
+ Data.CollectionJSON: instance Data.Aeson.Types.ToJSON.ToJSON Data.CollectionJSON.Template
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Collection
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Datum
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Error
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Item
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Link
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Query
+ Data.CollectionJSON: instance GHC.Classes.Eq Data.CollectionJSON.Template
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Collection
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Datum
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Error
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Item
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Link
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Query
+ Data.CollectionJSON: instance GHC.Show.Show Data.CollectionJSON.Template
+ Data.CollectionJSON: newtype Template
+ Data.CollectionJSON: toCollection :: ToCollection a => a -> Collection

Files

@@ -0,0 +1,1 @@+Copyright 2017 Alex Brandt <alunduil@alunduil.com>
+ ChangeLog.md view
@@ -0,0 +1,9 @@+# Revision history for collection-json++## 1.0.0.0  -- 2017-08-05++* Add Property Test Suite+* Add Code of Conduct+* Update README+* Add Travis CI Configuration+* Other Package Updates
README.md view
@@ -1,8 +1,35 @@-# collection-json+# Description -A Haskell supporting library for the Collection+JSON media type.+[Collection+JSON] Tools -In progess.+Types, classes, and functions for using the+[Collection+JSON—Hypermedia Type][Collection+JSON] in [Haskell]. +# Getting Started -See <http://amundsen.com/media-types/collection/> for information about this media type.+Documentation is available on [Hackage] and information about+`application/vnd.collection+json` can be found at+<http://amundsen.com/media-types/collection/>.++# Reporting Issues++Any issues discovered should be recorded on [github][issues].  If you believe+you've found an error or have a suggestion for a new feature; please, ensure+that it is reported.++If you would like to contribute a fix or new feature; please, submit a pull+request.  This project follows [git flow] and utilizes [travis] to automatically+check pull requests before a manual review.++# Contributors++The `COPYRIGHT` file contains a list of contributors with their respective+copyrights and other information.  If you submit a pull request and would like+attribution; please, add yourself to the `COPYRIGHT` file.++[Collection+JSON]: http://amundsen.com/media-types/collection/+[git flow]: http://nvie.com/posts/a-successful-git-branching-model/+[Hackage]: https://hackage.haskell.org/package/collection-json+[Haskell]: https://www.haskell.org/+[issues]: https://github.com/alunduil/collection-json.hs/issues+[travis]: https://travis-ci.org/alunduil/collection-json.hs
− Text/JSON/CollectionJSON/Types.hs
@@ -1,181 +0,0 @@-{-# LANGUAGE OverloadedStrings, RecordWildCards #-} -module Text.JSON.CollectionJSON.Types where-import Data.Aeson hiding (Error)-import Data.Text (Text)-import Control.Applicative--data Collection = Collection {-    cVersion :: Text-  , cHref :: Text-  , cLinks :: [Link]-  , cItems :: [Item]-  , cQueries :: [Query]-  , cTemplate :: Maybe Template-  , cError :: Maybe Error-  } deriving Show--data Error = Error {-    eTitle :: Text-  , eCode :: Maybe Text-  , eMessage :: Maybe Text-  } deriving Show--{- Each has five possible properties: href (REQUIRED), rel (REQURIED), name (OPTIONAL), render (OPTIONAL), and prompt, (OPTIONAL).--}--data Link = Link {-    lHref :: Text-  , lRel :: Text-  , lName :: Maybe Text-  , lRender :: Maybe Text-  , lPrompt :: Maybe Text-  } deriving Show-  -{- The queries array SHOULD contain one or more anonymous objects. Each object composed of five possible properties: href (REQUIRED), rel (REQUIRED), name (OPTIONAL), prompt (OPTIONAL), and a data array (OPTIONAL). -}--data Query = Query {-    qHref :: Text-  , qRel :: Text-  , qName :: Maybe Text-  , qPrompt :: Maybe Text-  , qData :: [Data]-  } deriving Show--{- The data array SHOULD contain one or more anonymous objects. Each -object MAY have any of three possible properties: name (REQUIRED), value-(OPTIONAL), and prompt (OPTIONAL). -}--data Data = Data { -    dName :: Text-  , dValue :: Maybe Text-  , dPrompt :: Maybe Text-  } deriving Show--{- Each element in the items array SHOULD contain an href property. The-href property MUST contain a URI. This URI MAY be used to retrieve a-Collection+JSON document representing the associated item. It MAY be used-to edit or delete the associated item. See Reading and Writing Data for-details.--The items array MAY have a data array child property.--The items array MAY have a links array child property.--}--data Item = Item {-    iHref :: Text-  , iData :: [Data]-  , iLinks :: [Link]-  } deriving Show--{- The template object SHOULD have a data array child property. -}---data Template = Template {-    tData :: [Data]-  } deriving Show- ---------------------------------------------------------------------------- FromJSON instances--instance FromJSON Template where-    parseJSON (Object v) = Template <$> v .: "data" --instance FromJSON Item where-    parseJSON (Object v) = Item -        <$> v .: "href" -        <*> v .:? "data" .!= [] -        <*> v .:? "links" .!= []--instance FromJSON Data where-    parseJSON (Object v) = Data-        <$> v .: "name"-        <*> v .:? "value"-        <*> v .:? "prompt"--instance FromJSON Query where-    parseJSON (Object v) = Query-        <$> v .: "href"-        <*> v .: "rel"-        <*> v .:? "name"-        <*> v .:? "prompt"-        <*> v .:? "data" .!= []--instance FromJSON Link where-    parseJSON (Object v) = Link-        <$> v .: "href"-        <*> v .: "rel"-        <*> v .:? "name"-        <*> v .:? "render"-        <*> v .:? "prompt"--instance FromJSON Error where-    parseJSON (Object v) = Error-        <$> v .: "title"-        <*> v .:? "code"-        <*> v .:? "message"--instance FromJSON Collection where-    parseJSON (Object v) = Collection -        <$> v .: "version" -        <*> v .: "href" -        <*> v .:? "links" .!= []-        <*> v .:? "items" .!= []-        <*> v .:? "queries" .!= []-        <*> v .:? "template" -        <*> v .:? "error" ----------------------------------------------------------------------------instance ToJSON Template where-    toJSON Template{..} = object [ "data" .= tData ]--instance ToJSON Item where-    toJSON Item{..} = object [ -        "href" .= iHref-      , "data" .= iData-      , "links" .= iLinks-      ]--instance ToJSON Data where-    toJSON Data{..} = object [ -        "name" .= dName-      , "data" .= dValue-      , "prompt" .= dPrompt-      ]--instance ToJSON Query where-    toJSON Query{..} = object [ -        "href" .= qHref-      , "rel" .= qRel-      , "name" .= qName-      , "prompt" .= qPrompt-      , "data" .= qData-      ]--instance ToJSON Link where-    toJSON Link{..} = object [ -        "href" .= lHref-      , "rel" .= lRel-      , "name" .= lName-      , "render" .= lRender-      , "prompt" .= lPrompt-      ]--instance ToJSON Error where-    toJSON Error{..} = object [ -        "title" .= eTitle-      , "code" .= eCode-      , "message" .= eMessage-      ]--instance ToJSON Collection where-    toJSON Collection{..} = object [ -        "version" .= cVersion-      , "href" .= cHref-      , "links" .= cLinks-      , "items" .= cItems-      , "queries" .= cQueries-      , "template" .= cTemplate-      , "error" .= cError-      ]
collection-json.cabal view
@@ -1,28 +1,88 @@--- Initial collection-json.cabal generated by cabal init.  For further --- documentation, see http://haskell.org/cabal/users-guide/- name:                collection-json-version:             0.1.0.0-synopsis:            Collection+JSON hypermedia type tools-homepage:            https://github.com/danchoi/collection-json.hs-description:         Collection+JSON hypermedia type tools+version:             1.0.0.0+synopsis:            Collection+JSON—Hypermedia Type Tools++description:+  Types, classes, and functions for using the Collection+JSON—Hypermedia Type+  in Haskell.++homepage:            https://github.com/alunduil/collection-json.hs+bug-reports:         https://github.com/alunduil/collection-json.hs/issues license:             MIT license-file:        LICENSE-author:              Daniel Choi-maintainer:          dhchoi@gmail.com-copyright:           2015 Daniel Choi-category:            Web+author:              Alex Brandt+maintainer:          alunduil@alunduil.com+copyright:           (c) 2017 Alex Brandt+category:            Data build-type:          Simple--- extra-source-files:   cabal-version:       >=1.10+tested-with:         GHC ==8.0.2 +extra-source-files:+    ChangeLog.md+  , COPYRIGHT+  , LICENSE+  , README.md+  , Setup.hs+  , test/Data/CollectionJSON/Tests.hs+  , test/Internal/Network/URI/Tests.hs+  , test/Main.hs++source-repository head+  type:     git+  location: https://github.com/alunduil/collection+json.hs+  branch:   develop+ library-  exposed-modules:     Text.JSON.CollectionJSON.Types-  -- other-modules:       -  -- other-extensions:    -  build-depends:       base >=4.6 && <4.8-                     , aeson >= 0.8-                     , text-                     , bytestring-  -- hs-source-dirs:      -  default-language:    Haskell2010+  default-language: Haskell2010+  hs-source-dirs:   src++  exposed-modules:+      Data.CollectionJSON++  ghc-options: -Wall -fwarn-tabs -fwarn-monomorphism-restriction+               -fwarn-unused-do-bind++  other-modules:+      Internal.Network.URI++  build-depends:+      aeson       >= 0.8 && < 1.1+    , base        >= 4.6 && < 4.10+    , network-uri == 2.6.*+    , text        == 1.2.*++  other-extensions:+      OverloadedStrings+    , RecordWildCards++test-suite Properties+  default-language: Haskell2010+  hs-source-dirs:   src test++  type:             exitcode-stdio-1.0+  main-is:          Main.hs++  ghc-options: -Wall -fwarn-tabs -fwarn-monomorphism-restriction+               -fwarn-unused-do-bind++  other-modules:+      Data.CollectionJSON+      Data.CollectionJSON.Tests++      Internal.Network.URI+      Internal.Network.URI.Tests++  build-depends:+      aeson                >= 0.8 && < 1.1+    , base                 >= 4.6 && < 4.10+    , network-uri          == 2.6.*+    , QuickCheck           == 2.9.*+    , quickcheck-instances == 0.3.*+    , test-invariant       == 0.4.*+    , text                 == 1.2.*++  other-extensions:+      OverloadedStrings+    , RecordWildCards+    , TemplateHaskell
+ src/Data/CollectionJSON.hs view
@@ -0,0 +1,235 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}++{-|+Module      : Data.CollectionJSON+Description : Types and Instances for @application/vnd.collection+json@+Copyright   : (c) Alex Brandt, 2017+License     : MIT++A collection of types and instances for @application/vnd.collection+json@.++Full documentation for @application/vnd.collection+json@ can be found at+<http://amundsen.com/media-types/collection/>.+-}+module Data.CollectionJSON where++import Data.Aeson ((.=), (.:?), (.!=), (.:), FromJSON (parseJSON), object, ToJSON (toJSON), withObject)+import Data.Text (Text)+import Network.URI (URI)++import Internal.Network.URI ()++-- * Core Data Types++-- | The top-level object for an @application/vnd.collection+json@ resource.+data Collection = Collection+  { cVersion  :: Text           -- ^ Currently, always "1.0".+  , cHref     :: URI            -- ^ Address used to retrieve the 'Collection'+                                --   and to add new elements.+  , 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"+    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+      [ "version"  .= cVersion+      , "href"     .= cHref+      , "links"    .= cLinks+      , "items"    .= cItems+      , "queries"  .= cQueries+      , "template" .= cTemplate+      , "error"    .= cError+      ]+    ]++{-|+A link to a related resource (not necessarily an+@application/vnd.collection+json@ resource).+-}+data Link = Link+  { lHref   :: URI        -- ^ Address of the resource.+  , lRel    :: Text       -- ^ Relation---the following contain suggested+                          --   relation values:+                          --+                          --   * [IANA Link Relations](http://www.iana.org/assignments/link-relations/link-relations.xml)+                          --   * [Microformat Existing Rel Values](http://microformats.org/wiki/existing-rel-values)+                          --   * [RFC5988](http://tools.ietf.org/html/rfc5988)+  , 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+    [ "href"   .= lHref+    , "rel"    .= lRel+    , "name"   .= lName+    , "render" .= lRender+    , "prompt" .= lPrompt+    ]++-- | An element in the 'Collection'+data Item = Item+  { iHref  :: URI    -- ^ Address of the resource used to retrieve, modify, or+                     --   delete the element.+  , 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+    [ "href"  .= iHref+    , "data"  .= iData+    , "links" .= iLinks+    ]++{-|+A template for possible queries related to this 'Collection'.++A query should correspond to an associated HTTP GET request.++The Query:+> Query "http://example.com/search" "search" Nothing (Just "Search:") [Datum "search" "" Nothing]++Corresponds with the following URI for an HTTP GET:+> http://example.com/search?search={search_terms}+-}+data Query = Query+  { qHref   :: URI        -- ^ Address of reqeust's target.+  , qRel    :: Text       -- ^ Relation---the following contain suggested+                          --   relation values:+                          --+                          --   * [IANA Link Relations](http://www.iana.org/assignments/link-relations/link-relations.xml)+                          --   * [Microformat Existing Rel Values](http://microformats.org/wiki/existing-rel-values)+                          --   * [RFC5988](http://tools.ietf.org/html/rfc5988)+  , qName   :: Maybe Text -- ^ Identifier for this 'Query'.+  , qPrompt :: Maybe Text -- ^ Suggested user prompt.+  , qData   :: [Datum]    -- ^ Query parameters for this 'Query'.+  } 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+    [ "href"   .= qHref+    , "rel"    .= qRel+    , "name"   .= qName+    , "prompt" .= qPrompt+    , "data"   .= qData+    ]++-- | A fillable template for creation of a new object in the 'Collection'.+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+    ]++-- | Information about latest error that occured when responding to a request.+data Error = Error+  { eTitle   :: Maybe Text+  , eCode    :: Maybe Text -- ^ Unique identifier (e.g. session identifier,+                           --   request tracker, etc).+  , 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+    [ "title"   .= eTitle+    , "code"    .= eCode+    , "message" .= eMessage+    ]++-- | Contents of a 'Collection' 'Item'.+data Datum = Datum+  { dName   :: Text       -- ^ Identifier for this 'Datum'.+  , dValue  :: Maybe Text+  , dPrompt :: Maybe Text -- ^ Suggested user prompt.+  } 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+    [ "name"   .= dName+    , "value"  .= dValue+    , "prompt" .= dPrompt+    ]++-- * Type Conversion++-- | A type that can be converted from 'Collection'.+class FromCollection a where+  fromCollection :: Collection -> a++-- | A type that can be converted to 'Collection'.+class ToCollection a where+  toCollection :: a -> Collection
+ src/Internal/Network/URI.hs view
@@ -0,0 +1,26 @@+{-# OPTIONS_GHC -Wno-orphans #-}++{-# LANGUAGE OverloadedStrings #-}++{-|+Module      : Internal.Network.URI+Description : URI Helper Functions+Copyright   : (c) Alex Brandt, 2017+License     : MIT++URI utility functions that don't belong anywhere else.+-}+module Internal.Network.URI where++import Data.Aeson (FromJSON (parseJSON), ToJSON (toJSON), withText)+import Data.Text (unpack)+import Network.URI (parseURIReference, URI)++instance FromJSON URI where+  parseJSON = withText "URI" $ \ v ->+    case parseURIReference (unpack v) of+      Nothing -> fail "invalid URI"+      Just x  -> return x++instance ToJSON URI where+  toJSON = toJSON . show
+ test/Data/CollectionJSON/Tests.hs view
@@ -0,0 +1,111 @@+{-# OPTIONS_GHC -Wno-orphans #-}++{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}++{-|+Module      : Data.CollectionJSON.Tests+Description : Tests for Data.CollectionJSON+Copyright   : (c) Alex Brandt, 2017+License     : MIT++Tests for "Data.CollectionJSON".+-}+module Data.CollectionJSON.Tests (runTests) where++import Data.Aeson (decode, encode)+import Data.Maybe (fromJust)+import Data.Text (pack)+import Test.Invariant ((<=>))+import Test.QuickCheck (Arbitrary (arbitrary), quickCheckAll)+import Test.QuickCheck.Instances ()++import Data.CollectionJSON+import Internal.Network.URI.Tests ()++prop_id_c :: Collection -> Bool+prop_id_c = fromJust . decode . encode <=> id++prop_id_l :: Link -> Bool+prop_id_l = fromJust . decode . encode <=> id++prop_id_i :: Item -> Bool+prop_id_i = fromJust . decode . encode <=> id++prop_id_q :: Query -> Bool+prop_id_q = fromJust . decode . encode <=> id++prop_id_t :: Template -> Bool+prop_id_t = fromJust . decode . encode <=> id++prop_id_e :: Error -> Bool+prop_id_e = fromJust . decode . encode <=> id++prop_id_d :: Datum -> Bool+prop_id_d = fromJust . decode . encode <=> id++return []+runTests :: IO Bool+runTests = $quickCheckAll++instance Arbitrary Collection where+  arbitrary =+    do let cVersion = pack "1.0"+       cHref     <- arbitrary+       cLinks    <- arbitrary+       cItems    <- arbitrary+       cQueries  <- arbitrary+       cTemplate <- arbitrary+       cError    <- arbitrary++       return Collection{..}++instance Arbitrary Link where+  arbitrary =+    do lHref   <- arbitrary+       lRel    <- arbitrary+       lName   <- arbitrary+       lRender <- arbitrary+       lPrompt <- arbitrary++       return Link{..}++instance Arbitrary Item where+  arbitrary =+    do iHref  <- arbitrary+       iData  <- arbitrary+       iLinks <- arbitrary++       return Item{..}++instance Arbitrary Query where+  arbitrary =+    do qHref   <- arbitrary+       qRel    <- arbitrary+       qName   <- arbitrary+       qPrompt <- arbitrary+       qData   <- arbitrary++       return Query{..}++instance Arbitrary Template where+  arbitrary =+    do tData <- arbitrary+       +       return Template{..}++instance Arbitrary Error where+  arbitrary =+    do eTitle   <- arbitrary+       eCode    <- arbitrary+       eMessage <- arbitrary++       return Error{..}++instance Arbitrary Datum where+  arbitrary =+    do dName   <- arbitrary+       dValue  <- arbitrary+       dPrompt <- arbitrary++       return Datum{..}
+ test/Internal/Network/URI/Tests.hs view
@@ -0,0 +1,49 @@+{-# OPTIONS_GHC -Wno-orphans #-}++{-# LANGUAGE RecordWildCards #-}++{-|+Module      : Internal.Network.URI.Tests+Description : URI Arbitrary Instances+Copyright   : (c) Alex Brandt, 2017+License     : MIT++A collection of 'Arbitrary' instances for 'URI'.+-}+module Internal.Network.URI.Tests where++import Data.Maybe (fromJust)+import Network.URI (parseURIReference, URI)+import Test.QuickCheck (Arbitrary (arbitrary), elements)++-- | Not a general implementation.+--+--   This implementation just returns a random URI from the+--   @application/vnd.collection+json@ examples.+instance Arbitrary URI where+  arbitrary = fromJust . parseURIReference <$> elements uris+    where uris = [ "http://example.org/friends/"+                 , "http://example.org/friends/"+                 , "http://example.org/friends/rss"+                 , "http://example.org/friends/jdoe"+                 , "http://examples.org/blogs/jdoe"+                 , "http://examples.org/images/jdoe"+                 , "http://example.org/friends/msmith"+                 , "http://examples.org/blogs/msmith"+                 , "http://examples.org/images/msmith"+                 , "http://example.org/friends/rwilliams"+                 , "http://examples.org/blogs/rwilliams"+                 , "http://examples.org/images/rwilliams"+                 , "http://example.org/friends/search"+                 , "http://example.org/friends/"+                 , "http://example.org/friends/rss"+                 , "http://example.org/friends/?queries"+                 , "http://example.org/friends/?template"+                 , "http://example.org/friends/jdoe"+                 , "http://examples.org/blogs/jdoe"+                 , "http://examples.org/images/jdoe"+                 , "http://example.org/friends/"+                 , "http://example.org/friends/search"+                 , "http://example.org/friends/"+                 , "http://example.org/friends/"+                 ]
+ test/Main.hs view
@@ -0,0 +1,17 @@+{-|+Module      : Main+Copyright   : (c) Alex Brandt, 2017+License     : MIT++"Main" Module for collection-json property tests.+-}+module Main where++import System.Exit (exitFailure, exitSuccess)++import qualified Data.CollectionJSON.Tests++main :: IO ()+main =+  do success <- and <$> sequence [ Data.CollectionJSON.Tests.runTests ]+     if success then exitSuccess else exitFailure