avro-0.3.6.0: test/Example1.hs
{-# LANGUAGE OverloadedStrings #-}
module Example1
where
import Data.Avro
import Data.Avro.Schema
import qualified Data.Avro.Types as Ty
import qualified Data.ByteString.Lazy as BL
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map as M
import Data.Text (Text)
import qualified Data.Text as Text
data MyEnum = A | B | C | D deriving (Eq,Ord,Show,Enum)
data MyStruct = MyStruct (Either MyEnum Text) Int deriving (Eq,Ord,Show)
-- Explicit 'Schema' types that specify the Avro encoding of a structure.
-- Schema's often come from an external JSON definition (.avsc files) or
-- embedded in object files.
meSchema :: Schema
meSchema = mkEnum "MyEnum" [] Nothing ["A","B","C","D"]
msSchema :: Schema
msSchema =
Record "MyStruct" [] Nothing Nothing
[ fld "enumOrString" eOrS (Just $ Ty.String "The Default")
, fld "intvalue" Long Nothing
]
where
fld nm ty def = Field nm [] Nothing Nothing ty def
eOrS = mkUnion (meSchema :| [String])
-- Encoding data, via the ToAvro class, requires both the routine that encodes
-- data as well as the schema under which it is encoded. The encoding and
-- schema must match, though there is no type or programmatic routine that enforces
-- this law.
instance HasAvroSchema MyEnum where
schema = pure meSchema
instance ToAvro MyEnum where
toAvro x = Ty.Enum meSchema (fromEnum x) (Text.pack $ show x)
-- schema = pure meSchema
instance HasAvroSchema MyStruct where
schema = pure msSchema
instance ToAvro MyStruct where
toAvro (MyStruct ab i) =
record msSchema
[ "enumOrString" .= ab
, "intvalue" .= i
]
-- schema = pure msSchema
-- Much like Aeson, decoding data is involves pattern matching the value
-- constructor then building the ADT.
instance FromAvro MyStruct where
fromAvro (Ty.Record _fs r) =
MyStruct <$> r .: "enumOrString"
<*> r .: "intvalue"
fromAvro v = badValue v "MyStruct"
instance FromAvro MyEnum where
fromAvro (Ty.Enum _ i _) = pure (toEnum i)
fromAvro v = badValue v "MyEnum"
main = do
let valR = MyStruct (Right "Hello") 1
encR = toAvro valR
valL = MyStruct (Left C) (negate 1944)
encL = toAvro valL
putStrLn "----------- MS Right value -------------"
print (fromAvro encR `asTypeOf` Success valR)
print (fromAvro encR == Success valR)
putStrLn "----------- MS Left value --------------"
print (fromAvro encL `asTypeOf` Success valL)
print (fromAvro encL == Success valL)
putStrLn "----------- MS Right full bytestring enc/dec--------------"
print (BL.unpack $ encode valR)
print (decode (encode valR) `asTypeOf` Success valR)
print (decode (encode valR) == Success valR)
putStrLn "----------- MS Left full bytestring enc/dec--------------"
print (BL.unpack $ encode valL)
print (decode (encode valL) `asTypeOf` Success valL)
print (decode (encode valL) == Success valL)