Hello community,

here is the log from the commit of package ghc-envelope for openSUSE:Factory 
checked in at 2017-03-03 17:50:05
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-envelope (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-envelope.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-envelope"

Fri Mar  3 17:50:05 2017 rev:2 rq:461627 version:0.2.1.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-envelope/ghc-envelope.changes        
2016-11-01 09:50:52.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-envelope.new/ghc-envelope.changes   
2017-03-03 17:50:06.417899365 +0100
@@ -1,0 +2,5 @@
+Sun Feb 12 14:15:17 UTC 2017 - [email protected]
+
+- Update to version 0.2.1.0 with cabal2obs.
+
+-------------------------------------------------------------------

Old:
----
  envelope-0.1.0.0.tar.gz

New:
----
  envelope-0.2.1.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-envelope.spec ++++++
--- /var/tmp/diff_new_pack.vFxemS/_old  2017-03-03 17:50:07.489747984 +0100
+++ /var/tmp/diff_new_pack.vFxemS/_new  2017-03-03 17:50:07.493747420 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-envelope
 #
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,16 +19,16 @@
 %global pkg_name envelope
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        0.1.0.0
+Version:        0.2.1.0
 Release:        0
 Summary:        Defines generic 'Envelope' type to wrap reponses from a JSON 
API
 License:        BSD-3-Clause
-Group:          System/Libraries
+Group:          Development/Languages/Other
 Url:            https://hackage.haskell.org/package/%{pkg_name}
 Source0:        
https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz
 BuildRequires:  ghc-Cabal-devel
-# Begin cabal-rpm deps:
 BuildRequires:  ghc-aeson-devel
+BuildRequires:  ghc-http-api-data-devel
 BuildRequires:  ghc-mtl-devel
 BuildRequires:  ghc-rpm-macros
 BuildRequires:  ghc-text-devel
@@ -37,7 +37,6 @@
 BuildRequires:  ghc-Glob-devel
 BuildRequires:  ghc-doctest-devel
 %endif
-# End cabal-rpm deps
 
 %description
 Please see README.md.
@@ -56,20 +55,14 @@
 %prep
 %setup -q -n %{pkg_name}-%{version}
 
-
 %build
 %ghc_lib_build
 
-
 %install
 %ghc_lib_install
 
-
 %check
-%if %{with tests}
-%{cabal} test
-%endif
-
+%cabal_test
 
 %post devel
 %ghc_pkg_recache
@@ -83,5 +76,6 @@
 
 %files devel -f %{name}-devel.files
 %defattr(-,root,root,-)
+%doc README.md
 
 %changelog

++++++ envelope-0.1.0.0.tar.gz -> envelope-0.2.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/envelope-0.1.0.0/README.md 
new/envelope-0.2.1.0/README.md
--- old/envelope-0.1.0.0/README.md      1970-01-01 01:00:00.000000000 +0100
+++ new/envelope-0.2.1.0/README.md      2016-10-27 09:06:53.000000000 +0200
@@ -0,0 +1,48 @@
+
+Web.Envelope
+============
+
+[![Hackage](https://img.shields.io/hackage/v/envelope.svg)](https://hackage.haskell.org/package/envelope)
 [![Build 
Status](https://secure.travis-ci.org/cdepillabout/envelope.svg)](http://travis-ci.org/cdepillabout/envelope)
+
+
+This module exports an `Envelope` type that can be used to wrap reponses from 
a JSON REST API.  It provides a successful `Success` response, and a failure 
`Err` response.
+
+Here is a small demonstration of returning a success response:
+
+```haskell
+>>> import qualified Data.ByteString.Lazy.Char8 as C8
+>>> import Data.Aeson (decode, encode)
+>>> let successEnvelope = toSuccessEnvelope 3 :: Envelope Text Int
+>>> C8.putStrLn $ encode successEnvelope
+{"data":3}
+>>> decode "{\"data\":3}" :: Maybe (Envelope Text Int)
+Just (EnvelopeSuccess (Success 3))
+```
+
+Your data gets wrapped in an object with a single `"data"` field:
+
+```json
+{
+    "data": 3
+}
+```
+
+Now lets look at how an error response is encoded and decoded.  It is encoded
+as an object with two members: @\"extra\"@ and @\"error\"@.
+
+```haskell
+>>> let errorEnvelope = toErrEnvelope "DB_ERROR" "there was an error in the 
database" :: Envelope String Int
+>>> C8.putStrLn $ encode errorEnvelope
+{"extra":"there was an error in the database","error":"DB_ERROR"}
+>>> decode "{\"extra\":\"there was an error in the 
database\",\"error\":\"DB_ERROR\"}" :: Maybe (Envelope String Int)
+Just (EnvelopeErr (Err {errErr = "DB_ERROR", errExtra = Just "there was an 
error in the database"}))
+```
+
+Your error type and extra message get wrapped in an object:
+
+```json
+{
+    "extra": "there was an error in the database",
+    "error": "DB_ERROR"
+}
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/envelope-0.1.0.0/envelope.cabal 
new/envelope-0.2.1.0/envelope.cabal
--- old/envelope-0.1.0.0/envelope.cabal 2016-04-06 08:09:35.000000000 +0200
+++ new/envelope-0.2.1.0/envelope.cabal 2016-10-27 09:35:54.000000000 +0200
@@ -1,5 +1,5 @@
 name:                envelope
-version:             0.1.0.0
+version:             0.2.1.0
 synopsis:            Defines generic 'Envelope' type to wrap reponses from a 
JSON API.
 description:         Please see README.md
 homepage:            https://github.com/cdepillabout/envelope#readme
@@ -10,7 +10,7 @@
 copyright:           2016 Dennis Gosnell
 category:            Web
 build-type:          Simple
--- extra-source-files:
+extra-source-files:  README.md
 cabal-version:       >=1.10
 
 library
@@ -18,6 +18,7 @@
   exposed-modules:     Web.Envelope
   build-depends:       base >= 4.8 && < 5
                      , aeson >= 0.11
+                     , http-api-data >= 0.3
                      , mtl >= 2.2
                      , text >= 1.2
   default-language:    Haskell2010
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/envelope-0.1.0.0/src/Web/Envelope.hs 
new/envelope-0.2.1.0/src/Web/Envelope.hs
--- old/envelope-0.1.0.0/src/Web/Envelope.hs    2016-04-07 06:07:26.000000000 
+0200
+++ new/envelope-0.2.1.0/src/Web/Envelope.hs    2016-10-27 09:34:27.000000000 
+0200
@@ -1,6 +1,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE InstanceSigs #-}
 {-# LANGUAGE OverloadedStrings #-}
 
@@ -48,6 +49,8 @@
     , Envelope'(..)
     , Success(..)
     , Err(..)
+    , toErr
+    , toErr'
     , throwEnvelopeErr
     , throwEnvelopeErr'
     , toSuccessEnvelope
@@ -59,15 +62,23 @@
 import Control.Monad.Except (MonadError, throwError)
 import Control.Applicative ((<|>))
 import Data.Aeson
-    ( (.=), (.:), FromJSON(..), ToJSON(..), Value(..), object )
+       ((.=), (.:), FromJSON(..), ToJSON(..), Value(..), object)
 import Data.Aeson.TH (deriveJSON)
 import Data.Aeson.Types (Parser, typeMismatch)
 import Data.Data (Data)
+import Data.Maybe (maybeToList)
 import Data.Text (Text)
 import Data.Typeable (Typeable)
 import GHC.Generics (Generic)
+import Web.FormUrlEncoded
+       (FromForm(fromForm), ToForm(toForm), fromEntriesByKey, lookupMaybe,
+        lookupUnique, parseUnique)
+import Web.HttpApiData
+       (FromHttpApiData, ToHttpApiData(toQueryParam))
+import Web.Internal.FormUrlEncoded (Form)
 
--- | Main type to be used.  Wrapper around responses from an API, mainly used 
with a JSON API.
+-- | Main type to be used.  Wrapper around responses from an API, mainly used
+-- with a JSON API.
 --
 -- Type synonym around 'Envelope''.
 type Envelope e a = Envelope' (Err e) (Success a)
@@ -95,15 +106,35 @@
               <|> EnvelopeErr     <$> parseJSON v
               <|> typeMismatch "Envelope'" v
 
--- | Newtype wrapper to be able to provide 'ToJSON' and 'FromJSON' instances.
--- Used with 'Envelope'.
+-- | Uses the underlying 'ToForm' instance for both the 'EnvelopeErr' case and
+-- the 'EnvelopeSuccess' case.
+instance (ToForm a, ToForm e) =>
+         ToForm (Envelope' e a) where
+  toForm :: Envelope' e a -> Form
+  toForm (EnvelopeErr err) = toForm err
+  toForm (EnvelopeSuccess succ) = toForm succ
+
+-- | Looks for the key @\"error\"@ in the 'Form'.  If it is found, assume this
+-- form is an @'Err e'@.  If it is not found, assume this 'Form' is an @a@.
+--
+-- __WARNING__: If the @a@ is encoded with a key @\"error\"@, this 'Form' will
+-- be decoded as a 'EnvelopeErr' instead of a 'EnvelopeSuccess'.  This is
+-- probably not what you want.
+instance (FromForm a, FromHttpApiData e) =>
+         FromForm (Envelope' (Err e) a) where
+  fromForm :: Form -> Either Text (Envelope' (Err e) a)
+  fromForm form =
+    case lookupUnique "error" form of
+      -- Key "error" doesn't exist, so assume this is an @a@.
+      Left _ -> EnvelopeSuccess <$> fromForm form
+      -- Key "error exists, so assume this is an @'Err' e@.
+      Right _ -> EnvelopeErr <$> fromForm form
+
+-- | Newtype wrapper to be able to provide specific instances. Used with
+-- 'Envelope'.
 newtype Success a = Success a
     deriving (Data, Eq, Generic, Show, Typeable)
 
-instance (ToJSON a) => ToJSON (Success a) where
-    toJSON :: Success a -> Value
-    toJSON (Success a) = object ["data" .= a]
-
 -- | For @'Success' a@, wrap the @a@ in an object with a @\"data\"@ field.
 --
 -- The resulting JSON object will look like this:
@@ -111,21 +142,35 @@
 -- @
 --  { \"data\": ... }
 -- @
+instance (ToJSON a) => ToJSON (Success a) where
+    toJSON :: Success a -> Value
+    toJSON (Success a) = object ["data" .= a]
+
+-- | Parse the JSON object produced by the 'ToJSON' instance.
 instance (FromJSON e) => FromJSON (Success e) where
     parseJSON :: Value -> Parser (Success e)
     parseJSON (Object v) = Success <$> v .: "data"
     parseJSON invalid    = typeMismatch "Success" invalid
 
--- | Newtype wrapper to be able to provide 'ToJSON' and 'FromJSON' instances.
+-- | Use the 'ToForm' instance of the underlying datatype.
+instance (ToForm a) =>
+         ToForm (Success a) where
+  toForm :: Success a -> Form
+  toForm (Success a) = toForm a
+
+-- | Use the 'FromForm' instance of the underlying datatype.
+instance (FromForm a) =>
+         FromForm (Success a) where
+  fromForm :: Form -> Either Text (Success a)
+  fromForm form = Success <$> fromForm form
+
+-- | Wrapper to add an extra field with info about the error.  Used with
+-- 'Envelope'.
 data Err e = Err { errErr   :: e          -- ^ Actual error information we 
want to send.
                  , errExtra :: Maybe Text -- ^ Additional error information in 
plain text.
                  }
     deriving (Data, Eq, Generic, Show, Typeable)
 
-instance (ToJSON e) => ToJSON (Err e) where
-    toJSON :: Err e -> Value
-    toJSON (Err e extra) = object ["error" .= e, "extra" .= extra]
-
 -- | For @'Err' e@, wrap the @e@ in an object with @\"extra\"@ and @\"error\"@ 
fields.
 --
 -- The resulting JSON object will look like this:
@@ -133,12 +178,52 @@
 -- @
 --  { \"extra\": ..., \"error\": .... }
 -- @
+instance (ToJSON e) => ToJSON (Err e) where
+    toJSON :: Err e -> Value
+    toJSON (Err e extra) = object ["error" .= e, "extra" .= extra]
+
+-- | Parse the JSON object produced by the 'ToJSON' instance.
 instance (FromJSON e) => FromJSON (Err e) where
     parseJSON :: Value -> Parser (Err e)
     parseJSON (Object v) = Err <$> v .: "error"
                                <*> v .: "extra"
     parseJSON invalid    = typeMismatch "Err" invalid
 
+-- | Just use the 'ToForm' instance of the underlying datatype.
+--
+-- The resulting Form object will look like this:
+--
+-- @
+--  [(\"extra\", ...), (\"error\", ....)]
+-- @
+instance (ToHttpApiData e) =>
+         ToForm (Err e) where
+  toForm :: Err e -> Form
+  toForm (Err err maybeExtra) =
+    fromEntriesByKey
+      [("error" :: Text, [toQueryParam err]), ("extra", maybeToList 
maybeExtra)]
+
+-- | Parse a form produced by the 'ToForm' instance.  Use 'FromHttpApiData's
+-- 'Web.HttpApiData.parseQueryParam' to parse the @error@ parameter.
+instance (FromHttpApiData e) =>
+         FromForm (Err e) where
+  fromForm :: Form -> Either Text (Err e)
+  fromForm form = Err <$> parseUnique "error" form <*> lookupMaybe "extra" form
+
+-- | Smart constructor for 'Err'.
+--
+-- >>> toErr "DB_ERROR" "an error occurred"
+-- Err {errErr = "DB_ERROR", errExtra = Just "an error occurred"}
+toErr :: e -> Text -> Err e
+toErr e extra = Err e (Just extra)
+
+-- | Smart constructor for 'Err' that doesn't use an 'errExtra'.
+--
+-- >>> toErr' "DB_ERROR"
+-- Err {errErr = "DB_ERROR", errExtra = Nothing}
+toErr' :: e -> Err e
+toErr' e = Err e Nothing
+
 -- | Wrap an @a@ in a success 'Envelope'.
 --
 -- >>> toSuccessEnvelope 3 :: Envelope String Int


Reply via email to