avro 0.2.1.0 → 0.2.1.1
raw patch · 5 files changed
+83/−57 lines, 5 files
Files
- avro.cabal +4/−3
- src/Data/Avro/Encode.hs +3/−3
- src/Data/Avro/Schema.hs +52/−51
- test/Avro/THEncodeContainerSpec.hs +17/−0
- test/data/maybe.avsc +7/−0
avro.cabal view
@@ -2,10 +2,10 @@ -- see http://haskell.org/cabal/users-guide/ name: avro-version: 0.2.1.0+version: 0.2.1.1 synopsis: Avro serialization support for Haskell description: Avro serialization and deserialization support for Haskell-homepage: https://github.com/haskell-works/hw-haskell-avro.git+homepage: https://github.com/GaloisInc/avro.git license: BSD3 license-file: LICENSE author: Thomas M. DuBuisson@@ -13,7 +13,7 @@ -- copyright: category: Data build-type: Simple-extra-source-files: ChangeLog.md, test/data/reused.avsc, test/data/small.avsc, test/data/enums.avsc+extra-source-files: ChangeLog.md, test/data/reused.avsc, test/data/small.avsc, test/data/enums.avsc, test/data/maybe.avsc cabal-version: >=1.10 source-repository head@@ -125,6 +125,7 @@ other-modules: Avro.THEnumSpec , Avro.THReusedSpec , Avro.THSimpleSpec+ , Avro.THEncodeContainerSpec main-is: Spec.hs ghc-options: -threaded
src/Data/Avro/Encode.hs view
@@ -91,13 +91,13 @@ -- encodeSchema = toLazyByteString . putAvro . getSchema putAvro :: EncodeAvro a => a -> Builder-putAvro = fst . runAvro . avro+putAvro = fst . runAvro . avro getSchema :: forall a. EncodeAvro a => a -> Schema-getSchema _ = getType (Proxy :: Proxy a)+getSchema = snd . runAvro . avro getType :: EncodeAvro a => Proxy a -> Type-getType p = snd (runAvro (avro (undefined `asProxyTypeOf` p)))+getType = getSchema . (asProxyTypeOf undefined) -- N.B. ^^^ Local knowledge that 'fst' won't be used, -- so the bottom of 'undefined' will not escape so long as schema creation -- remains lazy in the argument.
src/Data/Avro/Schema.hs view
@@ -1,9 +1,9 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-} -- | Avro 'Schema's, represented here as values of type 'Schema', -- describe the serialization and de-serialization of values. --@@ -24,32 +24,33 @@ , Result(..) ) where -import Prelude as P import Control.Applicative import Control.Monad.Except+import qualified Control.Monad.Fail as MF import Control.Monad.State.Strict-import qualified Control.Monad.Fail as MF-import qualified Data.Aeson as A-import Data.Aeson ((.=),object,(.:?),(.:),(.!=),FromJSON(..),ToJSON(..))-import Data.Aeson.Types (Parser,typeMismatch)-import qualified Data.ByteString.Base16 as Base16-import qualified Data.HashMap.Strict as HashMap+import Data.Aeson (FromJSON (..), ToJSON (..), object,+ (.!=), (.:), (.:!), (.:?), (.=))+import qualified Data.Aeson as A+import Data.Aeson.Types (Parser, typeMismatch)+import qualified Data.Avro.Types as Ty+import qualified Data.ByteString.Base16 as Base16 import Data.Hashable-import qualified Data.List as L-import Data.List.NonEmpty (NonEmpty(..))-import qualified Data.List.NonEmpty as NE-import Data.Maybe (catMaybes, fromMaybe)-import Data.Monoid ((<>), First(..))-import qualified Data.Set as S+import qualified Data.HashMap.Strict as HashMap+import Data.Int+import qualified Data.IntMap as IM+import qualified Data.List as L+import Data.List.NonEmpty (NonEmpty (..))+import qualified Data.List.NonEmpty as NE+import Data.Maybe (catMaybes, fromMaybe)+import Data.Monoid (First (..), (<>))+import qualified Data.Set as S import Data.String-import Data.Text (Text)-import qualified Data.Text as T-import Data.Text.Encoding as T-import qualified Data.Vector as V-import qualified Data.Avro.Types as Ty-import qualified Data.IntMap as IM-import Data.Int-import Text.Show.Functions+import Data.Text (Text)+import qualified Data.Text as T+import Data.Text.Encoding as T+import qualified Data.Vector as V+import Prelude as P+import Text.Show.Functions -- |An Avro schema is either -- * A "JSON object in the form `{"type":"typeName" ...`@@ -82,20 +83,20 @@ , order :: Maybe Order , fields :: [Field] }- | Enum { name :: TypeName- , namespace :: Maybe Text- , aliases :: [TypeName]- , doc :: Maybe Text- , symbols :: [Text]+ | Enum { name :: TypeName+ , namespace :: Maybe Text+ , aliases :: [TypeName]+ , doc :: Maybe Text+ , symbols :: [Text] , symbolLookup :: Int64 -> Maybe Text }- | Union { options :: NonEmpty Type+ | Union { options :: NonEmpty Type , unionLookup :: Int64 -> Maybe Type }- | Fixed { name :: TypeName- , namespace :: Maybe Text- , aliases :: [TypeName]- , size :: Int+ | Fixed { name :: TypeName+ , namespace :: Maybe Text+ , aliases :: [TypeName]+ , size :: Int } deriving (Show) @@ -167,12 +168,12 @@ Union (x:|_) _ -> typeName x _ -> unTN $ name bt -data Field = Field { fldName :: Text- , fldAliases :: [Text]- , fldDoc :: Maybe Text- , fldOrder :: Maybe Order- , fldType :: Type- , fldDefault :: Maybe (Ty.Value Type)+data Field = Field { fldName :: Text+ , fldAliases :: [Text]+ , fldDoc :: Maybe Text+ , fldOrder :: Maybe Order+ , fldType :: Type+ , fldDefault :: Maybe (Ty.Value Type) } deriving (Eq, Show) @@ -182,15 +183,15 @@ instance FromJSON Type where parseJSON (A.String s) = case s of- "null" -> return Null- "boolean" -> return Boolean- "int" -> return Int- "long" -> return Long- "float" -> return Float- "double" -> return Double- "bytes" -> return Bytes- "string" -> return String- somename -> return (NamedType (TN somename))+ "null" -> return Null+ "boolean" -> return Boolean+ "int" -> return Int+ "long" -> return Long+ "float" -> return Float+ "double" -> return Double+ "bytes" -> return Bytes+ "string" -> return String+ somename -> return (NamedType (TN somename)) parseJSON (A.Object o) = do ty <- o .: ("type" :: Text) case ty of@@ -272,7 +273,7 @@ instance FromJSON TypeName where parseJSON (A.String s) = return (TN s)- parseJSON j = typeMismatch "TypeName" j+ parseJSON j = typeMismatch "TypeName" j instance FromJSON Field where parseJSON (A.Object o) =@@ -280,7 +281,7 @@ doc <- o .:? "doc" ty <- o .: "type" let err = fail "Haskell Avro bindings does not support default for aliased or recursive types at this time."- defM <- o .:? "default"+ defM <- o .:! "default" def <- case parseAvroJSON err ty <$> defM of Just (Success x) -> return (Just x) Just (Error e) -> fail e@@ -349,7 +350,7 @@ instance MonadPlus Result where mzero = fail "mzero" mplus a@(Success _) _ = a- mplus _ b = b+ mplus _ b = b instance Monoid (Result a) where mempty = fail "Empty Result" mappend = mplus
+ test/Avro/THEncodeContainerSpec.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE TemplateHaskell #-}+module Avro.THEncodeContainerSpec where++import Data.Avro+import Data.Avro.Deriving++import Test.Hspec++import Control.Monad (void)+import Control.Exception++deriveAvro "test/data/record.avsc"++spec :: Spec+spec = describe "Avro.EncodeContainerSpec" $+ it "should encode data to a container of bytes" $+ (encodeContainer [[Thing 1]] >>= void . evaluate) `shouldReturn` ()
+ test/data/maybe.avsc view
@@ -0,0 +1,7 @@+{+ "type": "record",+ "name": "MaybeTest",+ "fields": [+ { "name": "tag", "type": ["null", "string"], "default": null }+ ]+ }