on develop help sign in
Merge pull request #58 from brendanhay/feature/base64-invalid-encoding
e5b42bbBrendan Hay
core/gogol-core.cabal+1−2
@@ -36,7 +36,7 @@ library
36 ghc-options: -Wall
36 ghc-options: -Wall
37
37
38 exposed-modules:
38 exposed-modules:
39− Network.Google.Data.Base64
39+ Network.Google.Data.Bytes
40 , Network.Google.Data.JSON
40 , Network.Google.Data.JSON
41 , Network.Google.Data.Numeric
41 , Network.Google.Data.Numeric
42 , Network.Google.Data.Time
42 , Network.Google.Data.Time
@@ -59,7 +59,6 @@ library
59 , http-media >= 0.6
59 , http-media >= 0.6
60 , http-types >= 0.8.6
60 , http-types >= 0.8.6
61 , lens >= 4.4
61 , lens >= 4.4
62− , memory >= 0.8
63 , resourcet >= 1.1
62 , resourcet >= 1.1
64 , scientific >= 0.3
63 , scientific >= 0.3
65 , servant >= 0.4.4
64 , servant >= 0.4.4
core/src/Network/Google/Data/Base64.hsdeleted−53
@@ -1,53 +0,0 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−{-# LANGUAGE DeriveGeneric #-}
3−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−
5−-- |
6−-- Module : Network.Google.Data.Base64
7−-- Copyright : (c) 2013-2016 Brendan Hay
8−-- License : Mozilla Public License, v. 2.0.
9−-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
10−-- Stability : provisional
11−-- Portability : non-portable (GHC extensions)
12−--
13−module Network.Google.Data.Base64
14− ( Base64 (..)
15− , _Base64
16− ) where
17−
18−import Control.Lens (Iso', iso)
19−import Data.Aeson (FromJSON (..), ToJSON (..))
20−import qualified Data.ByteArray.Encoding as BA
21−import Data.ByteString (ByteString)
22−import qualified Data.ByteString.Char8 as BS8
23−import Data.Data (Data, Typeable)
24−import Data.Hashable
25−import qualified Data.Text.Encoding as Text
26−import GHC.Generics (Generic)
27−import Network.Google.Data.JSON (parseJSONText, toJSONText)
28−import Web.HttpApiData (FromHttpApiData (..),
29− ToHttpApiData (..))
30−
31−-- | Base64 encoded binary data.
32−--
33−-- Encoding\/decoding is automatically deferred to serialisation and deserialisation
34−-- respectively.
35−newtype Base64 = Base64 { unBase64 :: ByteString }
36− deriving (Eq, Read, Ord, Data, Typeable, Generic)
37−
38−instance Hashable Base64
39−
40−_Base64 :: Iso' Base64 ByteString
41−_Base64 = iso unBase64 Base64
42−
43−instance ToHttpApiData Base64 where
44− toQueryParam = Text.decodeUtf8 . toHeader
45− toHeader = BA.convertToBase BA.Base64 . unBase64
46−
47−instance FromHttpApiData Base64 where
48− parseQueryParam = parseHeader . Text.encodeUtf8
49− parseHeader = either fail (pure . Base64) . BA.convertFromBase BA.Base64
50−
51−instance Show Base64 where show = show . BS8.unpack . unBase64
52−instance FromJSON Base64 where parseJSON = parseJSONText "Base64"
53−instance ToJSON Base64 where toJSON = toJSONText
core/src/Network/Google/Data/Bytes.hsnew file+49
@@ -0,0 +1,49 @@
1+{-# LANGUAGE DeriveDataTypeable #-}
2+{-# LANGUAGE DeriveGeneric #-}
3+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4+
5+-- |
6+-- Module : Network.Google.Data.Bytes
7+-- Copyright : (c) 2013-2016 Brendan Hay
8+-- License : Mozilla Public License, v. 2.0.
9+-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
10+-- Stability : provisional
11+-- Portability : non-portable (GHC extensions)
12+--
13+module Network.Google.Data.Bytes
14+ ( Bytes (..)
15+ , _Bytes
16+ ) where
17+
18+import Control.Lens (Iso', iso)
19+import Data.Aeson (FromJSON (..), ToJSON (..))
20+import Data.ByteString (ByteString)
21+import Data.Data (Data, Typeable)
22+import Data.Hashable
23+import qualified Data.Text.Encoding as Text
24+import GHC.Generics (Generic)
25+import Network.Google.Data.JSON (parseJSONText, toJSONText)
26+import Web.HttpApiData (FromHttpApiData (..),
27+ ToHttpApiData (..))
28+-- | Binary data.
29+--
30+-- This data is passed to/from the serialisation routines as-is, and any
31+-- particular encoding or decoding (say, base64) is left up to the caller.
32+newtype Bytes = Bytes { unBytes :: ByteString }
33+ deriving (Eq, Show, Read, Ord, Data, Typeable, Generic)
34+
35+instance Hashable Bytes
36+
37+_Bytes :: Iso' Bytes ByteString
38+_Bytes = iso unBytes Bytes
39+
40+instance ToHttpApiData Bytes where
41+ toQueryParam = Text.decodeUtf8 . unBytes
42+ toHeader = unBytes
43+
44+instance FromHttpApiData Bytes where
45+ parseQueryParam = pure . Bytes . Text.encodeUtf8
46+ parseHeader = pure . Bytes
47+
48+instance FromJSON Bytes where parseJSON = parseJSONText "Bytes"
49+instance ToJSON Bytes where toJSON = toJSONText
core/src/Network/Google/Prelude.hs+1−1
@@ -31,7 +31,7 @@ import Servant.API as Export hiding (Headers, getResponse)
31import Servant.Utils.Links as Export hiding (Link)
31import Servant.Utils.Links as Export hiding (Link)
32import Web.HttpApiData as Export (FromHttpApiData (..), ToHttpApiData (..))
32import Web.HttpApiData as Export (FromHttpApiData (..), ToHttpApiData (..))
33
33
34−import Network.Google.Data.Base64 as Export
34+import Network.Google.Data.Bytes as Export
35import Network.Google.Data.JSON as Export
35import Network.Google.Data.JSON as Export
36import Network.Google.Data.Numeric as Export
36import Network.Google.Data.Numeric as Export
37import Network.Google.Data.Time as Export
37import Network.Google.Data.Time as Export
gen/.ghcinew file+3
@@ -0,0 +1,3 @@
1+:set -XOverloadedStrings
2+
3+:set prompt "> "
gen/gogol-gen.cabal+3−3
@@ -44,7 +44,7 @@ executable gogol-gen
44 ghc-options: -Wall -threaded
44 ghc-options: -Wall -threaded
45
45
46 build-depends:
46 build-depends:
47− aeson
47+ aeson >= 1
48 , attoparsec
48 , attoparsec
49 , base >= 4.8
49 , base >= 4.8
50 , bifunctors
50 , bifunctors
@@ -55,8 +55,8 @@ executable gogol-gen
55 , errors >= 2.1.2
55 , errors >= 2.1.2
56 , formatting
56 , formatting
57 , hashable
57 , hashable
58− , haskell-src-exts >= 1.17.1
58+ , haskell-src-exts == 1.17.1
59− , hindent
59+ , hindent < 5
60 , lens
60 , lens
61 , mtl
61 , mtl
62 , optparse-applicative
62 , optparse-applicative
gen/src/Gen/Orphans.hs−11
@@ -11,14 +11,9 @@
11
11
12module Gen.Orphans where
12module Gen.Orphans where
13
13
14−import Data.Aeson
15−import Data.Bifunctor
16import Data.Hashable
14import Data.Hashable
17−import qualified Data.HashMap.Strict as Map
18import Data.String
15import Data.String
19−import qualified Data.Text as Text
20import Language.Haskell.Exts.Build
16import Language.Haskell.Exts.Build
21−import Language.Haskell.Exts.Pretty
22import Language.Haskell.Exts.Syntax
17import Language.Haskell.Exts.Syntax
23
18
24instance Hashable Name
19instance Hashable Name
@@ -26,9 +21,3 @@ instance Hashable Name
26instance IsString Name where fromString = name
21instance IsString Name where fromString = name
27instance IsString QName where fromString = UnQual . name
22instance IsString QName where fromString = UnQual . name
28instance IsString QOp where fromString = op . sym
23instance IsString QOp where fromString = op . sym
29−
30−instance ToJSON a => ToJSON (Map.HashMap Name a) where
31− toJSON = toJSON
32− . Map.fromList
33− . map (first (Text.pack . prettyPrint))
34− . Map.toList
gen/src/Gen/Syntax.hs+2−2
@@ -588,7 +588,7 @@ internalLit = \case
588 Nat -> TyApp (TyCon "Textual") (TyCon "Nat")
588 Nat -> TyApp (TyCon "Textual") (TyCon "Nat")
589 Float -> TyApp (TyCon "Textual") (TyCon "Double")
589 Float -> TyApp (TyCon "Textual") (TyCon "Double")
590 Double -> TyApp (TyCon "Textual") (TyCon "Double")
590 Double -> TyApp (TyCon "Textual") (TyCon "Double")
591− Byte -> TyCon "Base64"
591+ Byte -> TyCon "Bytes"
592 UInt32 -> TyApp (TyCon "Textual") (TyCon "Word32")
592 UInt32 -> TyApp (TyCon "Textual") (TyCon "Word32")
593 UInt64 -> TyApp (TyCon "Textual") (TyCon "Word64")
593 UInt64 -> TyApp (TyCon "Textual") (TyCon "Word64")
594 Int32 -> TyApp (TyCon "Textual") (TyCon "Int32")
594 Int32 -> TyApp (TyCon "Textual") (TyCon "Int32")
@@ -622,7 +622,7 @@ iso = \case
622 TLit Duration -> Just (var "_Duration")
622 TLit Duration -> Just (var "_Duration")
623 TLit Float -> Just (var "_Coerce")
623 TLit Float -> Just (var "_Coerce")
624 TLit Double -> Just (var "_Coerce")
624 TLit Double -> Just (var "_Coerce")
625− TLit Byte -> Just (var "_Base64")
625+ TLit Byte -> Just (var "_Bytes")
626 TLit UInt32 -> Just (var "_Coerce")
626 TLit UInt32 -> Just (var "_Coerce")
627 TLit UInt64 -> Just (var "_Coerce")
627 TLit UInt64 -> Just (var "_Coerce")
628 TLit Int32 -> Just (var "_Coerce")
628 TLit Int32 -> Just (var "_Coerce")
gen/src/Gen/Types/Data.hs−1
@@ -31,7 +31,6 @@ import Data.Text (Text)
31import qualified Data.Text as Text
31import qualified Data.Text as Text
32import qualified Data.Text.Lazy as LText
32import qualified Data.Text.Lazy as LText
33import Data.Text.Manipulate
33import Data.Text.Manipulate
34−import Gen.Orphans ()
35import Gen.Types.Help
34import Gen.Types.Help
36import Gen.Types.Id
35import Gen.Types.Id
37import Gen.Types.NS
36import Gen.Types.NS
gen/src/Gen/Types/Id.hs+15−13
@@ -58,12 +58,10 @@ import Control.Applicative
58import Control.Monad
58import Control.Monad
59import Data.Aeson hiding (Bool, String)
59import Data.Aeson hiding (Bool, String)
60import qualified Data.Attoparsec.Text as A
60import qualified Data.Attoparsec.Text as A
61−import Data.Bifunctor (first)
62import qualified Data.CaseInsensitive as CI
61import qualified Data.CaseInsensitive as CI
63import Data.Foldable (foldl')
62import Data.Foldable (foldl')
64import Data.Function (on)
63import Data.Function (on)
65import Data.Hashable
64import Data.Hashable
66−import qualified Data.HashMap.Strict as Map
67import Data.List (intersperse)
65import Data.List (intersperse)
68import Data.List (elemIndex, nub, sortOn)
66import Data.List (elemIndex, nub, sortOn)
69import Data.Semigroup hiding (Sum)
67import Data.Semigroup hiding (Sum)
@@ -73,9 +71,7 @@ import qualified Data.Text as Text
73import qualified Data.Text.Lazy.Builder as Build
71import qualified Data.Text.Lazy.Builder as Build
74import Data.Text.Manipulate
72import Data.Text.Manipulate
75import Formatting
73import Formatting
76−import Gen.Orphans ()
77import Gen.Text
74import Gen.Text
78−import Gen.Types.Map
79import GHC.Generics (Generic)
75import GHC.Generics (Generic)
80import Language.Haskell.Exts.Build
76import Language.Haskell.Exts.Build
81import Language.Haskell.Exts.Syntax (Exp, Name (..))
77import Language.Haskell.Exts.Syntax (Exp, Name (..))
@@ -164,22 +160,28 @@ instance IsString Global where
164instance FromJSON Global where
160instance FromJSON Global where
165 parseJSON = withText "global" (pure . mkGlobal)
161 parseJSON = withText "global" (pure . mkGlobal)
166
162
163+instance FromJSONKey Global where
164+ fromJSONKey = FromJSONKeyText mkGlobal
165+
167instance ToJSON Global where
166instance ToJSON Global where
168 toJSON = toJSON . global
167 toJSON = toJSON . global
169
168
170−instance FromJSON v => FromJSON (Map Global v) where
171− parseJSON = fmap (Map.fromList . map (first mkGlobal) . Map.toList)
172− . parseJSON
173−
174gid :: Format a (Global -> a)
169gid :: Format a (Global -> a)
175gid = later (Build.fromText . global)
170gid = later (Build.fromText . global)
176
171
177newtype Local = Local { local :: Text }
172newtype Local = Local { local :: Text }
178− deriving (Eq, Ord, Show, Generic, Hashable, FromJSON, ToJSON, IsString)
173+ deriving
179−
174+ ( Eq
180−instance FromJSON v => FromJSON (Map Local v) where
175+ , Ord
181− parseJSON = fmap (Map.fromList . map (first Local) . Map.toList)
176+ , Show
182− . parseJSON
177+ , Generic
178+ , Hashable
179+ , FromJSON
180+ , ToJSON
181+ , FromJSONKey
182+ , ToJSONKey
183+ , IsString
184+ )
183
185
184lid :: Format a (Local -> a)
186lid :: Format a (Local -> a)
185lid = later (Build.fromText . local)
187lid = later (Build.fromText . local)
gen/src/Gen/Types/Schema.hs−1
@@ -38,7 +38,6 @@ import Data.Semigroup ((<>))
38import Data.Text (Text)
38import Data.Text (Text)
39import qualified Data.Text as Text
39import qualified Data.Text as Text
40import Data.Text.Manipulate
40import Data.Text.Manipulate
41−import Gen.Orphans ()
42import Gen.Text
41import Gen.Text
43import Gen.TH
42import Gen.TH
44import Gen.Types.Help
43import Gen.Types.Help
gen/src/Main.hs+2−1
@@ -18,6 +18,7 @@ import Control.Error
18import Control.Lens hiding ((<.>))
18import Control.Lens hiding ((<.>))
19import Control.Monad.State
19import Control.Monad.State
20import Data.List (nub, sort)
20import Data.List (nub, sort)
21+import Data.Monoid ((<>))
21import Data.String
22import Data.String
22import qualified Data.Text as Text
23import qualified Data.Text as Text
23import qualified Filesystem as FS
24import qualified Filesystem as FS
@@ -152,7 +153,7 @@ main = do
152 let anx = _optAnnexes </> fromText modelName <.> "json"
153 let anx = _optAnnexes </> fromText modelName <.> "json"
153 p <- isFile anx
154 p <- isFile anx
154 if not p
155 if not p
155− then say ("Skipping '" % stext % "' due to mimsing annex configuration.")
156+ then say ("Skipping '" % stext % "' due to missing annex configuration.")
156 modelName
157 modelName
157 else do
158 else do
158 s <- sequence
159 s <- sequence
gen/stack.yaml+2
@@ -5,6 +5,8 @@ flags: {}
5
5
6extra-deps:
6extra-deps:
7 - text-regex-replace-0.1.1.1
7 - text-regex-replace-0.1.1.1
8+ - haskell-src-exts-1.17.1
9+ - hindent-4.6.4
8
10
9packages:
11packages:
10 - '.'
12 - '.'