{-# language ConstraintKinds       #-}
{-# language DataKinds             #-}
{-# language FlexibleContexts      #-}
{-# language FlexibleInstances     #-}
{-# language GADTs                 #-}
{-# language MultiParamTypeClasses #-}
{-# language PolyKinds             #-}
{-# language RankNTypes            #-}
{-# language ScopedTypeVariables   #-}
{-# language TypeApplications      #-}
{-# language TypeFamilies          #-}
{-# language TypeOperators         #-}
{-# language UndecidableInstances  #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-|
Description : Adapter for Avro serialization

Just import the module and you can turn any
value with a 'ToSchema' and 'FromSchema' from
and to Avro values.
-}
module Mu.Adapter.Avro () where

import           Control.Applicative                 ((<|>))
import           Control.Arrow                       ((***))
import qualified Data.Avro                           as A
import qualified Data.Avro.Encoding.FromAvro         as AVal
import qualified Data.Avro.Encoding.ToAvro           as A
import qualified Data.Avro.Schema.ReadSchema         as RSch
import qualified Data.Avro.Schema.Schema             as ASch
-- 'Tagged . unTagged' can be replaced by 'coerce'
-- eliminating some run-time overhead
import           Data.Avro.EitherN                   (putIndexedValue)
import           Data.ByteString.Builder             (Builder, word8)
import           Data.Coerce                         (coerce)
import qualified Data.HashMap.Strict                 as HM
import           Data.List                           ((\\))
import           Data.List.NonEmpty                  (NonEmpty (..))
import qualified Data.List.NonEmpty                  as NonEmptyList
import qualified Data.Map                            as M
import           Data.Maybe                          (fromJust)
import           Data.Tagged
import qualified Data.Text                           as T
import qualified Data.Vector                         as V
import           GHC.TypeLits

import           Mu.Schema
import qualified Mu.Schema.Interpretation.Schemaless as SLess

instance SLess.ToSchemalessTerm AVal.Value where
  toSchemalessTerm :: Value -> Term
toSchemalessTerm (AVal.Record s :: ReadSchema
s r :: Vector Value
r)
    = case ReadSchema
s of
        RSch.Record { fields :: ReadSchema -> [ReadField]
RSch.fields = [ReadField]
fs }
          -> [Field] -> Term
SLess.TRecord ([Field] -> Term) -> [Field] -> Term
forall a b. (a -> b) -> a -> b
$ ((Text, Value) -> Field) -> [(Text, Value)] -> [Field]
forall a b. (a -> b) -> [a] -> [b]
map (\(k :: Text
k,v :: Value
v) -> Text -> FieldValue -> Field
SLess.Field Text
k (Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue Value
v))
                           ([(Text, Value)] -> [Field]) -> [(Text, Value)] -> [Field]
forall a b. (a -> b) -> a -> b
$ [Text] -> [Value] -> [(Text, Value)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((ReadField -> Text) -> [ReadField] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ReadField -> Text
RSch.fldName [ReadField]
fs) (Vector Value -> [Value]
forall a. Vector a -> [a]
V.toList Vector Value
r)
        _ -> [Char] -> Term
forall a. HasCallStack => [Char] -> a
error ("this should never happen:\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ReadSchema -> [Char]
forall a. Show a => a -> [Char]
show ReadSchema
s)
  toSchemalessTerm (AVal.Enum _ i :: Int
i _)
    = Int -> Term
SLess.TEnum Int
i
  toSchemalessTerm (AVal.Union _ _ v :: Value
v)
    = Value -> Term
forall t. ToSchemalessTerm t => t -> Term
SLess.toSchemalessTerm Value
v
  toSchemalessTerm v :: Value
v = FieldValue -> Term
SLess.TSimple (Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue Value
v)

instance SLess.ToSchemalessValue AVal.Value where
  toSchemalessValue :: Value -> FieldValue
toSchemalessValue AVal.Null         = FieldValue
SLess.FNull
  toSchemalessValue (AVal.Boolean  b :: Bool
b) = Bool -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Bool
b
  toSchemalessValue (AVal.Int    _ b :: Int32
b) = Int32 -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Int32
b
  toSchemalessValue (AVal.Long   _ b :: Int64
b) = Int64 -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Int64
b
  toSchemalessValue (AVal.Float  _ b :: Float
b) = Float -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Float
b
  toSchemalessValue (AVal.Double _ b :: Double
b) = Double -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Double
b
  toSchemalessValue (AVal.String _ b :: Text
b) = Text -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Text
b
  toSchemalessValue (AVal.Fixed  _ b :: ByteString
b) = ByteString -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive ByteString
b
  toSchemalessValue (AVal.Bytes  _ b :: ByteString
b) = ByteString -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive ByteString
b
  toSchemalessValue (AVal.Array v :: Vector Value
v)
    = [FieldValue] -> FieldValue
SLess.FList ([FieldValue] -> FieldValue) -> [FieldValue] -> FieldValue
forall a b. (a -> b) -> a -> b
$ (Value -> FieldValue) -> [Value] -> [FieldValue]
forall a b. (a -> b) -> [a] -> [b]
map Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue ([Value] -> [FieldValue]) -> [Value] -> [FieldValue]
forall a b. (a -> b) -> a -> b
$ Vector Value -> [Value]
forall a. Vector a -> [a]
V.toList Vector Value
v
  toSchemalessValue (AVal.Map hm :: HashMap Text Value
hm)
    = Map FieldValue FieldValue -> FieldValue
SLess.FMap (Map FieldValue FieldValue -> FieldValue)
-> Map FieldValue FieldValue -> FieldValue
forall a b. (a -> b) -> a -> b
$ [(FieldValue, FieldValue)] -> Map FieldValue FieldValue
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList
                 ([(FieldValue, FieldValue)] -> Map FieldValue FieldValue)
-> [(FieldValue, FieldValue)] -> Map FieldValue FieldValue
forall a b. (a -> b) -> a -> b
$ ((Text, Value) -> (FieldValue, FieldValue))
-> [(Text, Value)] -> [(FieldValue, FieldValue)]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive (Text -> FieldValue)
-> (Value -> FieldValue)
-> (Text, Value)
-> (FieldValue, FieldValue)
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue)
                 ([(Text, Value)] -> [(FieldValue, FieldValue)])
-> [(Text, Value)] -> [(FieldValue, FieldValue)]
forall a b. (a -> b) -> a -> b
$ HashMap Text Value -> [(Text, Value)]
forall k v. HashMap k v -> [(k, v)]
HM.toList HashMap Text Value
hm
  toSchemalessValue (AVal.Union _ _ v :: Value
v)
    = Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue Value
v
  toSchemalessValue r :: Value
r@(AVal.Record _ _)
    = Term -> FieldValue
SLess.FSchematic (Value -> Term
forall t. ToSchemalessTerm t => t -> Term
SLess.toSchemalessTerm Value
r)
  toSchemalessValue e :: Value
e@AVal.Enum {}
    = Term -> FieldValue
SLess.FSchematic (Value -> Term
forall t. ToSchemalessTerm t => t -> Term
SLess.toSchemalessTerm Value
e)

instance (HasAvroSchemas sch sch)
         => A.HasAvroSchema (WithSchema sch sty t) where
  schema :: Tagged (WithSchema sch sty t) Schema
schema = Schema -> Tagged (WithSchema sch sty t) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (WithSchema sch sty t) Schema)
-> Schema -> Tagged (WithSchema sch sty t) Schema
forall a b. (a -> b) -> a -> b
$ Vector Schema -> Schema
ASch.Union (Vector Schema -> Schema) -> Vector Schema -> Schema
forall a b. (a -> b) -> a -> b
$ Proxy sch -> Proxy sch -> [TypeName] -> Vector Schema
forall tn fn (r :: Schema tn fn) (sch :: Schema tn fn).
HasAvroSchemas r sch =>
Proxy r -> Proxy sch -> [TypeName] -> Vector Schema
schemas (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch) (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch) [TypeName]
ts
    where ts :: [TypeName]
ts = Proxy sch -> Proxy sch -> [TypeName]
forall tn fn (r :: Schema tn fn) (sch :: Schema tn fn).
HasAvroSchemas r sch =>
Proxy r -> Proxy sch -> [TypeName]
typeNames (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch) (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch)
instance ( FromSchema sch sty t
         , A.FromAvro (Term sch (sch :/: sty)) )
         => A.FromAvro (WithSchema sch sty t) where
  fromAvro :: Value -> Either [Char] (WithSchema sch sty t)
fromAvro entire :: Value
entire@(AVal.Union _ _ v :: Value
v)
    =   -- remove first layer of union
        t -> WithSchema sch sty t
forall tn fn (sch :: Schema tn fn) (sty :: tn) a.
a -> WithSchema sch sty a
WithSchema (t -> WithSchema sch sty t)
-> (Term sch (sch :/: sty) -> t)
-> Term sch (sch :/: sty)
-> WithSchema sch sty t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
forall fn tn (sch :: Schema tn fn) t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
fromSchema' @_ @_ @sch (Term sch (sch :/: sty) -> WithSchema sch sty t)
-> Either [Char] (Term sch (sch :/: sty))
-> Either [Char] (WithSchema sch sty t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Term sch (sch :/: sty))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
    Either [Char] (WithSchema sch sty t)
-> Either [Char] (WithSchema sch sty t)
-> Either [Char] (WithSchema sch sty t)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> -- try with the entire thing
        t -> WithSchema sch sty t
forall tn fn (sch :: Schema tn fn) (sty :: tn) a.
a -> WithSchema sch sty a
WithSchema (t -> WithSchema sch sty t)
-> (Term sch (sch :/: sty) -> t)
-> Term sch (sch :/: sty)
-> WithSchema sch sty t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
forall fn tn (sch :: Schema tn fn) t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
fromSchema' @_ @_ @sch (Term sch (sch :/: sty) -> WithSchema sch sty t)
-> Either [Char] (Term sch (sch :/: sty))
-> Either [Char] (WithSchema sch sty t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Term sch (sch :/: sty))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
entire
  fromAvro entire :: Value
entire
    =   t -> WithSchema sch sty t
forall tn fn (sch :: Schema tn fn) (sty :: tn) a.
a -> WithSchema sch sty a
WithSchema (t -> WithSchema sch sty t)
-> (Term sch (sch :/: sty) -> t)
-> Term sch (sch :/: sty)
-> WithSchema sch sty t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
forall fn tn (sch :: Schema tn fn) t (sty :: tn).
FromSchema sch sty t =>
Term sch (sch :/: sty) -> t
fromSchema' @_ @_ @sch (Term sch (sch :/: sty) -> WithSchema sch sty t)
-> Either [Char] (Term sch (sch :/: sty))
-> Either [Char] (WithSchema sch sty t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Term sch (sch :/: sty))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
entire
instance ( ToSchema sch sty t
         , A.ToAvro (Term sch (sch :/: sty))
         , KnownNat (IxOf sch sty) )
         => A.ToAvro (WithSchema sch sty t) where
  toAvro :: Schema -> WithSchema sch sty t -> Builder
toAvro (ASch.Union vs :: Vector Schema
vs) (WithSchema v :: t
v)
    = Int -> Vector Schema -> Term sch (sch :/: sty) -> Builder
forall a. ToAvro a => Int -> Vector Schema -> a -> Builder
putIndexedValue (Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> Integer -> Int
forall a b. (a -> b) -> a -> b
$ Proxy (IxOf sch sty) -> Integer
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Integer
natVal (Proxy (IxOf sch sty)
forall k (t :: k). Proxy t
Proxy @(IxOf sch sty)))
                      Vector Schema
vs
                      (t -> Term sch (sch :/: sty)
forall fn tn (sch :: Schema tn fn) t (sty :: tn).
ToSchema sch sty t =>
t -> Term sch (sch :/: sty)
toSchema' @_ @_ @sch t
v)
  toAvro s :: Schema
s _ = [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ("this should never happen:\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Schema -> [Char]
forall a. Show a => a -> [Char]
show Schema
s)

class HasAvroSchemas (r :: Schema tn fn) (sch :: Schema tn fn) where
  schemas   :: Proxy r -> Proxy sch -> [ASch.TypeName] -> V.Vector ASch.Schema
  typeNames :: Proxy r -> Proxy sch -> [ASch.TypeName]
instance HasAvroSchemas r '[] where
  schemas :: Proxy r -> Proxy '[] -> [TypeName] -> Vector Schema
schemas _ _ _ = Vector Schema
forall a. Vector a
V.empty
  typeNames :: Proxy r -> Proxy '[] -> [TypeName]
typeNames _ _ = []
instance forall r d ds.
         (HasAvroSchema' (Term r d), HasAvroSchemas r ds)
         => HasAvroSchemas r (d ': ds) where
  schemas :: Proxy r -> Proxy (d : ds) -> [TypeName] -> Vector Schema
schemas pr :: Proxy r
pr _ tys :: [TypeName]
tys = Schema -> Vector Schema -> Vector Schema
forall a. a -> Vector a -> Vector a
V.cons Schema
thisSchema (Proxy r -> Proxy ds -> [TypeName] -> Vector Schema
forall tn fn (r :: Schema tn fn) (sch :: Schema tn fn).
HasAvroSchemas r sch =>
Proxy r -> Proxy sch -> [TypeName] -> Vector Schema
schemas Proxy r
pr (Proxy ds
forall k (t :: k). Proxy t
Proxy @ds) [TypeName]
tys)
    where thisSchema :: Schema
thisSchema = Tagged (Term r d) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (Term r d) Schema -> Schema)
-> Tagged (Term r d) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (Term r d) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(Term r d) ([TypeName]
tys [TypeName] -> [TypeName] -> [TypeName]
forall a. Eq a => [a] -> [a] -> [a]
\\ Proxy (Term r d) -> [TypeName]
forall k (x :: k). HasAvroSchema' x => Proxy x -> [TypeName]
typeName' (Proxy (Term r d)
forall k (t :: k). Proxy t
Proxy @(Term r d)))
  typeNames :: Proxy r -> Proxy (d : ds) -> [TypeName]
typeNames pr :: Proxy r
pr _ = Proxy (Term r d) -> [TypeName]
forall k (x :: k). HasAvroSchema' x => Proxy x -> [TypeName]
typeName' (Proxy (Term r d)
forall k (t :: k). Proxy t
Proxy @(Term r d)) [TypeName] -> [TypeName] -> [TypeName]
forall a. [a] -> [a] -> [a]
++ Proxy r -> Proxy ds -> [TypeName]
forall tn fn (r :: Schema tn fn) (sch :: Schema tn fn).
HasAvroSchemas r sch =>
Proxy r -> Proxy sch -> [TypeName]
typeNames Proxy r
pr (Proxy ds
forall k (t :: k). Proxy t
Proxy @ds)

type family IxOf (sch :: Schema tn fn) (sty :: tn) :: Nat where
  IxOf ('DRecord nm fs ': rest) nm = 0
  IxOf ('DEnum   nm cs ': rest) nm = 0
  IxOf (other          ': rest) nm = 1 + IxOf rest nm

-- HasAvroSchema instances

class HasAvroSchema' x where
  typeName' :: Proxy x -> [ASch.TypeName]
  schema' :: [ASch.TypeName] -> Tagged x ASch.Schema

instance TypeError ('Text "you should never use HasAvroSchema directly on Term, use WithSchema")
         => A.HasAvroSchema (Term sch t) where
  schema :: Tagged (Term sch t) Schema
schema = [Char] -> Tagged (Term sch t) Schema
forall a. HasCallStack => [Char] -> a
error "this should never happen"
instance HasAvroSchema' (FieldValue sch t)
         => A.HasAvroSchema (FieldValue sch t) where
  schema :: Tagged (FieldValue sch t) Schema
schema = [TypeName] -> Tagged (FieldValue sch t) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' []

instance (KnownName name, HasAvroSchemaFields sch args)
         => HasAvroSchema' (Term sch ('DRecord name args)) where
  typeName' :: Proxy (Term sch ('DRecord name args)) -> [TypeName]
typeName' _ = [Proxy name -> TypeName
forall k (s :: k) (proxy :: k -> *).
KnownName s =>
proxy s -> TypeName
nameTypeName (Proxy name
forall k (t :: k). Proxy t
Proxy @name)]
  schema' :: [TypeName] -> Tagged (Term sch ('DRecord name args)) Schema
schema' visited :: [TypeName]
visited
    = if TypeName
recordName TypeName -> [TypeName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TypeName]
visited
         then Schema -> Tagged (Term sch ('DRecord name args)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (Term sch ('DRecord name args)) Schema)
-> Schema -> Tagged (Term sch ('DRecord name args)) Schema
forall a b. (a -> b) -> a -> b
$ TypeName -> Schema
ASch.NamedType TypeName
recordName
         else Schema -> Tagged (Term sch ('DRecord name args)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (Term sch ('DRecord name args)) Schema)
-> Schema -> Tagged (Term sch ('DRecord name args)) Schema
forall a b. (a -> b) -> a -> b
$ TypeName -> [TypeName] -> Maybe Text -> [Field] -> Schema
ASch.Record TypeName
recordName [] Maybe Text
forall a. Maybe a
Nothing [Field]
fields
    where recordName :: TypeName
recordName = Proxy name -> TypeName
forall k (s :: k) (proxy :: k -> *).
KnownName s =>
proxy s -> TypeName
nameTypeName (Proxy name
forall k (t :: k). Proxy t
Proxy @name)
          fields :: [Field]
fields = Proxy sch -> Proxy args -> [TypeName] -> [Field]
forall k tn fn (sch :: k) (fs :: [FieldDef tn fn]).
HasAvroSchemaFields sch fs =>
Proxy sch -> Proxy fs -> [TypeName] -> [Field]
schemaF (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch) (Proxy args
forall k (t :: k). Proxy t
Proxy @args) [TypeName]
visited
instance (KnownName name, HasAvroSchemaEnum choices)
          => HasAvroSchema' (Term sch ('DEnum name choices)) where
  typeName' :: Proxy (Term sch ('DEnum name choices)) -> [TypeName]
typeName' _ = [Proxy name -> TypeName
forall k (s :: k) (proxy :: k -> *).
KnownName s =>
proxy s -> TypeName
nameTypeName (Proxy name
forall k (t :: k). Proxy t
Proxy @name)]
  schema' :: [TypeName] -> Tagged (Term sch ('DEnum name choices)) Schema
schema' visited :: [TypeName]
visited
    = if TypeName
enumName TypeName -> [TypeName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [TypeName]
visited
         then Schema -> Tagged (Term sch ('DEnum name choices)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (Term sch ('DEnum name choices)) Schema)
-> Schema -> Tagged (Term sch ('DEnum name choices)) Schema
forall a b. (a -> b) -> a -> b
$ TypeName -> Schema
ASch.NamedType TypeName
enumName
         else Schema -> Tagged (Term sch ('DEnum name choices)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (Term sch ('DEnum name choices)) Schema)
-> Schema -> Tagged (Term sch ('DEnum name choices)) Schema
forall a b. (a -> b) -> a -> b
$ TypeName -> [TypeName] -> Maybe Text -> [Text] -> Schema
ASch.mkEnum TypeName
enumName [] Maybe Text
forall a. Maybe a
Nothing [Text]
choicesNames
    where enumName :: TypeName
enumName = Proxy name -> TypeName
forall k (s :: k) (proxy :: k -> *).
KnownName s =>
proxy s -> TypeName
nameTypeName (Proxy name
forall k (t :: k). Proxy t
Proxy @name)
          choicesNames :: [Text]
choicesNames = Proxy choices -> [Text]
forall fn (fs :: [ChoiceDef fn]).
HasAvroSchemaEnum fs =>
Proxy fs -> [Text]
schemaE (Proxy choices
forall k (t :: k). Proxy t
Proxy @choices)
instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (Term sch ('DSimple t)) where
  typeName' :: Proxy (Term sch ('DSimple t)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (Term sch ('DSimple t)) Schema
schema' visited :: [TypeName]
visited = Tagged (FieldValue sch t) Schema
-> Tagged (Term sch ('DSimple t)) Schema
forall a b. Coercible a b => a -> b
coerce (Tagged (FieldValue sch t) Schema
 -> Tagged (Term sch ('DSimple t)) Schema)
-> Tagged (FieldValue sch t) Schema
-> Tagged (Term sch ('DSimple t)) Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch t) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch t) [TypeName]
visited

instance HasAvroSchema' (FieldValue sch 'TNull) where
  typeName' :: Proxy (FieldValue sch 'TNull) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch 'TNull) Schema
schema' _ = Schema -> Tagged (FieldValue sch 'TNull) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged Schema
ASch.Null
instance A.HasAvroSchema t
         => HasAvroSchema' (FieldValue sch ('TPrimitive t)) where
  typeName' :: Proxy (FieldValue sch ('TPrimitive t)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch ('TPrimitive t)) Schema
schema' _ = Tagged t Schema -> Tagged (FieldValue sch ('TPrimitive t)) Schema
forall a b. Coercible a b => a -> b
coerce (Tagged t Schema -> Tagged (FieldValue sch ('TPrimitive t)) Schema)
-> Tagged t Schema
-> Tagged (FieldValue sch ('TPrimitive t)) Schema
forall a b. (a -> b) -> a -> b
$ HasAvroSchema t => Tagged t Schema
forall a. HasAvroSchema a => Tagged a Schema
A.schema @t
instance (HasAvroSchema' (Term sch (sch :/: t)))
         => HasAvroSchema' (FieldValue sch ('TSchematic t)) where
  typeName' :: Proxy (FieldValue sch ('TSchematic t)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch ('TSchematic t)) Schema
schema' visited :: [TypeName]
visited = Tagged (Term sch (sch :/: t)) Schema
-> Tagged (FieldValue sch ('TSchematic t)) Schema
forall a b. Coercible a b => a -> b
coerce (Tagged (Term sch (sch :/: t)) Schema
 -> Tagged (FieldValue sch ('TSchematic t)) Schema)
-> Tagged (Term sch (sch :/: t)) Schema
-> Tagged (FieldValue sch ('TSchematic t)) Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (Term sch (sch :/: t)) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(Term sch (sch :/: t)) [TypeName]
visited
instance forall sch choices.
         HasAvroSchemaUnion (FieldValue sch) choices
         => HasAvroSchema' (FieldValue sch ('TUnion choices)) where
  typeName' :: Proxy (FieldValue sch ('TUnion choices)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch ('TUnion choices)) Schema
schema' visited :: [TypeName]
visited
    = Schema -> Tagged (FieldValue sch ('TUnion choices)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (FieldValue sch ('TUnion choices)) Schema)
-> Schema -> Tagged (FieldValue sch ('TUnion choices)) Schema
forall a b. (a -> b) -> a -> b
$ NonEmpty Schema -> Schema
ASch.mkUnion (NonEmpty Schema -> Schema) -> NonEmpty Schema -> Schema
forall a b. (a -> b) -> a -> b
$ Proxy (FieldValue sch)
-> Proxy choices -> [TypeName] -> NonEmpty Schema
forall k (f :: k -> *) (xs :: [k]).
HasAvroSchemaUnion f xs =>
Proxy f -> Proxy xs -> [TypeName] -> NonEmpty Schema
schemaU (Proxy (FieldValue sch)
forall k (t :: k). Proxy t
Proxy @(FieldValue sch)) (Proxy choices
forall k (t :: k). Proxy t
Proxy @choices) [TypeName]
visited
instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (FieldValue sch ('TOption t)) where
  typeName' :: Proxy (FieldValue sch ('TOption t)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch ('TOption t)) Schema
schema' visited :: [TypeName]
visited
    = Schema -> Tagged (FieldValue sch ('TOption t)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (FieldValue sch ('TOption t)) Schema)
-> Schema -> Tagged (FieldValue sch ('TOption t)) Schema
forall a b. (a -> b) -> a -> b
$ NonEmpty Schema -> Schema
ASch.mkUnion (NonEmpty Schema -> Schema) -> NonEmpty Schema -> Schema
forall a b. (a -> b) -> a -> b
$ Schema
ASch.Null Schema -> [Schema] -> NonEmpty Schema
forall a. a -> [a] -> NonEmpty a
:| [Schema
iSchema]
    where iSchema :: Schema
iSchema = Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> Tagged (FieldValue sch t) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch t) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch t) [TypeName]
visited
instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (FieldValue sch ('TList t)) where
  typeName' :: Proxy (FieldValue sch ('TList t)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName] -> Tagged (FieldValue sch ('TList t)) Schema
schema' visited :: [TypeName]
visited
    = Schema -> Tagged (FieldValue sch ('TList t)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema -> Tagged (FieldValue sch ('TList t)) Schema)
-> Schema -> Tagged (FieldValue sch ('TList t)) Schema
forall a b. (a -> b) -> a -> b
$ Schema -> Schema
ASch.Array Schema
iSchema
    where iSchema :: Schema
iSchema = Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> Tagged (FieldValue sch t) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch t) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch t) [TypeName]
visited
-- These are the only two versions of Map supported by the library
instance HasAvroSchema' (FieldValue sch v)
         => HasAvroSchema' (FieldValue sch ('TMap ('TPrimitive T.Text) v)) where
  typeName' :: Proxy (FieldValue sch ('TMap ('TPrimitive Text) v)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName]
-> Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
schema' visited :: [TypeName]
visited
    = Schema
-> Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema
 -> Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema)
-> Schema
-> Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
forall a b. (a -> b) -> a -> b
$ Schema -> Schema
ASch.Map Schema
iSchema
    where iSchema :: Schema
iSchema = Tagged (FieldValue sch v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch v) Schema -> Schema)
-> Tagged (FieldValue sch v) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch v) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch v) [TypeName]
visited
instance HasAvroSchema' (FieldValue sch v)
         => HasAvroSchema' (FieldValue sch ('TMap ('TPrimitive String) v)) where
  typeName' :: Proxy (FieldValue sch ('TMap ('TPrimitive [Char]) v)) -> [TypeName]
typeName' _ = []
  schema' :: [TypeName]
-> Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
schema' visited :: [TypeName]
visited
    = Schema
-> Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
forall k (s :: k) b. b -> Tagged s b
Tagged (Schema
 -> Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema)
-> Schema
-> Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
forall a b. (a -> b) -> a -> b
$ Schema -> Schema
ASch.Map Schema
iSchema
    where iSchema :: Schema
iSchema = Tagged (FieldValue sch v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch v) Schema -> Schema)
-> Tagged (FieldValue sch v) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch v) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch v) [TypeName]
visited

class HasAvroSchemaUnion (f :: k -> *) (xs :: [k]) where
  schemaU :: Proxy f -> Proxy xs -> [ASch.TypeName] -> NonEmpty ASch.Schema
instance HasAvroSchema' (f v) => HasAvroSchemaUnion f '[v] where
  schemaU :: Proxy f -> Proxy '[v] -> [TypeName] -> NonEmpty Schema
schemaU _ _ visited :: [TypeName]
visited = Schema
vSchema Schema -> [Schema] -> NonEmpty Schema
forall a. a -> [a] -> NonEmpty a
:| []
    where vSchema :: Schema
vSchema = Tagged (f v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged ([TypeName] -> Tagged (f v) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(f v) [TypeName]
visited)
instance (HasAvroSchema' (f x), HasAvroSchemaUnion f (y ': zs))
         => HasAvroSchemaUnion f (x ': y ': zs) where
  schemaU :: Proxy f -> Proxy (x : y : zs) -> [TypeName] -> NonEmpty Schema
schemaU p :: Proxy f
p _ visited :: [TypeName]
visited = Schema
xSchema Schema -> [Schema] -> NonEmpty Schema
forall a. a -> [a] -> NonEmpty a
:| NonEmpty Schema -> [Schema]
forall a. NonEmpty a -> [a]
NonEmptyList.toList NonEmpty Schema
yzsSchema
    where xSchema :: Schema
xSchema = Tagged (f x) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged ([TypeName] -> Tagged (f x) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(f x) [TypeName]
visited)
          yzsSchema :: NonEmpty Schema
yzsSchema = Proxy f -> Proxy (y : zs) -> [TypeName] -> NonEmpty Schema
forall k (f :: k -> *) (xs :: [k]).
HasAvroSchemaUnion f xs =>
Proxy f -> Proxy xs -> [TypeName] -> NonEmpty Schema
schemaU Proxy f
p (Proxy (y : zs)
forall k (t :: k). Proxy t
Proxy @(y ': zs)) [TypeName]
visited

class HasAvroSchemaFields sch (fs :: [FieldDef tn fn]) where
  schemaF :: Proxy sch -> Proxy fs -> [ASch.TypeName] -> [ASch.Field]
instance HasAvroSchemaFields sch '[] where
  schemaF :: Proxy sch -> Proxy '[] -> [TypeName] -> [Field]
schemaF _ _ _ = []
instance (KnownName name, HasAvroSchema' (FieldValue sch t), HasAvroSchemaFields sch fs)
         => HasAvroSchemaFields sch ('FieldDef name t ': fs) where
  schemaF :: Proxy sch -> Proxy ('FieldDef name t : fs) -> [TypeName] -> [Field]
schemaF psch :: Proxy sch
psch _ visited :: [TypeName]
visited = Field
schemaThis Field -> [Field] -> [Field]
forall a. a -> [a] -> [a]
: Proxy sch -> Proxy fs -> [TypeName] -> [Field]
forall k tn fn (sch :: k) (fs :: [FieldDef tn fn]).
HasAvroSchemaFields sch fs =>
Proxy sch -> Proxy fs -> [TypeName] -> [Field]
schemaF Proxy sch
psch (Proxy fs
forall k (t :: k). Proxy t
Proxy @fs) [TypeName]
visited
    where fieldName :: Text
fieldName = Proxy name -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy name
forall k (t :: k). Proxy t
Proxy @name)
          schemaT :: Schema
schemaT = Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> Tagged (FieldValue sch t) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (FieldValue sch t) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(FieldValue sch t) [TypeName]
visited
          schemaThis :: Field
schemaThis = Text
-> [Text]
-> Maybe Text
-> Maybe Order
-> Schema
-> Maybe DefaultValue
-> Field
ASch.Field Text
fieldName [] Maybe Text
forall a. Maybe a
Nothing Maybe Order
forall a. Maybe a
Nothing Schema
schemaT Maybe DefaultValue
forall a. Maybe a
Nothing

class HasAvroSchemaEnum (fs :: [ChoiceDef fn]) where
  schemaE :: Proxy fs -> [T.Text]
instance HasAvroSchemaEnum '[] where
  schemaE :: Proxy '[] -> [Text]
schemaE _ = []
instance (KnownName name, HasAvroSchemaEnum fs)
         => HasAvroSchemaEnum ('ChoiceDef name ': fs) where
  schemaE :: Proxy ('ChoiceDef name : fs) -> [Text]
schemaE _ = Proxy name -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy name
forall k (t :: k). Proxy t
Proxy @name) Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Proxy fs -> [Text]
forall fn (fs :: [ChoiceDef fn]).
HasAvroSchemaEnum fs =>
Proxy fs -> [Text]
schemaE (Proxy fs
forall k (t :: k). Proxy t
Proxy @fs)

-- FromAvro instances

instance (KnownName name, FromAvroFields sch args)
         => A.FromAvro (Term sch ('DRecord name args)) where
  fromAvro :: Value -> Either [Char] (Term sch ('DRecord name args))
fromAvro (AVal.Record RSch.Record { fields :: ReadSchema -> [ReadField]
RSch.fields = [ReadField]
fs } fields :: Vector Value
fields)
    = NP (Field sch) args -> Term sch ('DRecord name args)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (args :: [FieldDef typeName fieldName]) (name :: typeName).
NP (Field sch) args -> Term sch ('DRecord name args)
TRecord (NP (Field sch) args -> Term sch ('DRecord name args))
-> Either [Char] (NP (Field sch) args)
-> Either [Char] (Term sch ('DRecord name args))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HashMap Text Value -> Either [Char] (NP (Field sch) args)
forall (sch :: Schema Symbol Symbol)
       (fs :: [FieldDef Symbol Symbol]).
FromAvroFields sch fs =>
HashMap Text Value -> Either [Char] (NP (Field sch) fs)
fromAvroF HashMap Text Value
r
    where
      r :: HashMap Text Value
r = [(Text, Value)] -> HashMap Text Value
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(Text, Value)] -> HashMap Text Value)
-> [(Text, Value)] -> HashMap Text Value
forall a b. (a -> b) -> a -> b
$ [Text] -> [Value] -> [(Text, Value)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((ReadField -> Text) -> [ReadField] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map ReadField -> Text
RSch.fldName [ReadField]
fs) (Vector Value -> [Value]
forall a. Vector a -> [a]
V.toList Vector Value
fields)
  fromAvro _ = [Char] -> Either [Char] (Term sch ('DRecord name args))
forall a b. a -> Either a b
Left "expecting record"
instance (KnownName name, FromAvroEnum choices)
          => A.FromAvro (Term sch ('DEnum name choices)) where
  fromAvro :: Value -> Either [Char] (Term sch ('DEnum name choices))
fromAvro (AVal.Enum _ _ v :: Text
v) = NS Proxy choices -> Term sch ('DEnum name choices)
forall fieldName typeName (choices :: [ChoiceDef fieldName])
       (sch :: Schema typeName fieldName) (name :: typeName).
NS Proxy choices -> Term sch ('DEnum name choices)
TEnum (NS Proxy choices -> Term sch ('DEnum name choices))
-> Either [Char] (NS Proxy choices)
-> Either [Char] (Term sch ('DEnum name choices))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Either [Char] (NS Proxy choices)
forall fn (vs :: [ChoiceDef fn]).
FromAvroEnum vs =>
Text -> Either [Char] (NS Proxy vs)
fromAvroEnum Text
v
  fromAvro _                 = [Char] -> Either [Char] (Term sch ('DEnum name choices))
forall a b. a -> Either a b
Left "expecting enum"
instance (A.FromAvro (FieldValue sch t))
         => A.FromAvro (Term sch ('DSimple t)) where
  fromAvro :: Value -> Either [Char] (Term sch ('DSimple t))
fromAvro v :: Value
v = FieldValue sch t -> Term sch ('DSimple t)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (t1 :: FieldType typeName).
FieldValue sch t1 -> Term sch ('DSimple t1)
TSimple (FieldValue sch t -> Term sch ('DSimple t))
-> Either [Char] (FieldValue sch t)
-> Either [Char] (Term sch ('DSimple t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (FieldValue sch t)
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v

instance A.FromAvro (FieldValue sch 'TNull) where
  fromAvro :: Value -> Either [Char] (FieldValue sch 'TNull)
fromAvro AVal.Null = FieldValue sch 'TNull -> Either [Char] (FieldValue sch 'TNull)
forall (f :: * -> *) a. Applicative f => a -> f a
pure FieldValue sch 'TNull
forall typeName fieldName (sch :: Schema typeName fieldName).
FieldValue sch 'TNull
FNull
  fromAvro _         = [Char] -> Either [Char] (FieldValue sch 'TNull)
forall a b. a -> Either a b
Left "expecting null"
instance A.FromAvro t => A.FromAvro (FieldValue sch ('TPrimitive t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TPrimitive t))
fromAvro v :: Value
v = t -> FieldValue sch ('TPrimitive t)
forall typeName fieldName t1 (sch :: Schema typeName fieldName).
t1 -> FieldValue sch ('TPrimitive t1)
FPrimitive (t -> FieldValue sch ('TPrimitive t))
-> Either [Char] t
-> Either [Char] (FieldValue sch ('TPrimitive t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] t
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
instance ( KnownName t, A.FromAvro (Term sch (sch :/: t)) )
         => A.FromAvro (FieldValue sch ('TSchematic t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TSchematic t))
fromAvro v :: Value
v = Term sch (sch :/: t) -> FieldValue sch ('TSchematic t)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (t1 :: typeName).
Term sch (sch :/: t1) -> FieldValue sch ('TSchematic t1)
FSchematic (Term sch (sch :/: t) -> FieldValue sch ('TSchematic t))
-> Either [Char] (Term sch (sch :/: t))
-> Either [Char] (FieldValue sch ('TSchematic t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Term sch (sch :/: t))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
instance (FromAvroUnion sch choices)
         => A.FromAvro (FieldValue sch ('TUnion choices)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TUnion choices))
fromAvro (AVal.Union _ i :: Int
i v :: Value
v) = NS (FieldValue sch) choices -> FieldValue sch ('TUnion choices)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (choices :: [FieldType typeName]).
NS (FieldValue sch) choices -> FieldValue sch ('TUnion choices)
FUnion (NS (FieldValue sch) choices -> FieldValue sch ('TUnion choices))
-> Either [Char] (NS (FieldValue sch) choices)
-> Either [Char] (FieldValue sch ('TUnion choices))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Value -> Either [Char] (NS (FieldValue sch) choices)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (choices :: [FieldType typeName]).
FromAvroUnion sch choices =>
Int -> Value -> Either [Char] (NS (FieldValue sch) choices)
fromAvroU Int
i Value
v
  fromAvro _                  = [Char] -> Either [Char] (FieldValue sch ('TUnion choices))
forall a b. a -> Either a b
Left "expecting union"
instance (A.FromAvro (FieldValue sch t))
         => A.FromAvro (FieldValue sch ('TOption t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TOption t))
fromAvro v :: Value
v = Maybe (FieldValue sch t) -> FieldValue sch ('TOption t)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (t1 :: FieldType typeName).
Maybe (FieldValue sch t1) -> FieldValue sch ('TOption t1)
FOption (Maybe (FieldValue sch t) -> FieldValue sch ('TOption t))
-> Either [Char] (Maybe (FieldValue sch t))
-> Either [Char] (FieldValue sch ('TOption t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Maybe (FieldValue sch t))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
instance (A.FromAvro (FieldValue sch t))
         => A.FromAvro (FieldValue sch ('TList t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TList t))
fromAvro v :: Value
v = [FieldValue sch t] -> FieldValue sch ('TList t)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (t1 :: FieldType typeName).
[FieldValue sch t1] -> FieldValue sch ('TList t1)
FList ([FieldValue sch t] -> FieldValue sch ('TList t))
-> Either [Char] [FieldValue sch t]
-> Either [Char] (FieldValue sch ('TList t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] [FieldValue sch t]
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
-- These are the only two versions of Map supported by the library
instance (A.FromAvro (FieldValue sch v))
         => A.FromAvro (FieldValue sch ('TMap ('TPrimitive T.Text) v)) where
  fromAvro :: Value
-> Either [Char] (FieldValue sch ('TMap ('TPrimitive Text) v))
fromAvro v :: Value
v = Map (FieldValue sch ('TPrimitive Text)) (FieldValue sch v)
-> FieldValue sch ('TMap ('TPrimitive Text) v)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (k :: FieldType typeName) (v :: FieldType typeName).
Ord (FieldValue sch k) =>
Map (FieldValue sch k) (FieldValue sch v)
-> FieldValue sch ('TMap k v)
FMap (Map (FieldValue sch ('TPrimitive Text)) (FieldValue sch v)
 -> FieldValue sch ('TMap ('TPrimitive Text) v))
-> (Map Text (FieldValue sch v)
    -> Map (FieldValue sch ('TPrimitive Text)) (FieldValue sch v))
-> Map Text (FieldValue sch v)
-> FieldValue sch ('TMap ('TPrimitive Text) v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> FieldValue sch ('TPrimitive Text))
-> Map Text (FieldValue sch v)
-> Map (FieldValue sch ('TPrimitive Text)) (FieldValue sch v)
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeys Text -> FieldValue sch ('TPrimitive Text)
forall typeName fieldName t1 (sch :: Schema typeName fieldName).
t1 -> FieldValue sch ('TPrimitive t1)
FPrimitive (Map Text (FieldValue sch v)
 -> FieldValue sch ('TMap ('TPrimitive Text) v))
-> Either [Char] (Map Text (FieldValue sch v))
-> Either [Char] (FieldValue sch ('TMap ('TPrimitive Text) v))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Map Text (FieldValue sch v))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
instance (A.FromAvro (FieldValue sch v))
         => A.FromAvro (FieldValue sch ('TMap ('TPrimitive String) v)) where
  fromAvro :: Value
-> Either [Char] (FieldValue sch ('TMap ('TPrimitive [Char]) v))
fromAvro v :: Value
v = Map (FieldValue sch ('TPrimitive [Char])) (FieldValue sch v)
-> FieldValue sch ('TMap ('TPrimitive [Char]) v)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (k :: FieldType typeName) (v :: FieldType typeName).
Ord (FieldValue sch k) =>
Map (FieldValue sch k) (FieldValue sch v)
-> FieldValue sch ('TMap k v)
FMap (Map (FieldValue sch ('TPrimitive [Char])) (FieldValue sch v)
 -> FieldValue sch ('TMap ('TPrimitive [Char]) v))
-> (Map Text (FieldValue sch v)
    -> Map (FieldValue sch ('TPrimitive [Char])) (FieldValue sch v))
-> Map Text (FieldValue sch v)
-> FieldValue sch ('TMap ('TPrimitive [Char]) v)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> FieldValue sch ('TPrimitive [Char]))
-> Map Text (FieldValue sch v)
-> Map (FieldValue sch ('TPrimitive [Char])) (FieldValue sch v)
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeys ([Char] -> FieldValue sch ('TPrimitive [Char])
forall typeName fieldName t1 (sch :: Schema typeName fieldName).
t1 -> FieldValue sch ('TPrimitive t1)
FPrimitive ([Char] -> FieldValue sch ('TPrimitive [Char]))
-> (Text -> [Char]) -> Text -> FieldValue sch ('TPrimitive [Char])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Char]
T.unpack) (Map Text (FieldValue sch v)
 -> FieldValue sch ('TMap ('TPrimitive [Char]) v))
-> Either [Char] (Map Text (FieldValue sch v))
-> Either [Char] (FieldValue sch ('TMap ('TPrimitive [Char]) v))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (Map Text (FieldValue sch v))
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v

class FromAvroEnum (vs :: [ChoiceDef fn]) where
  fromAvroEnum :: T.Text -> Either String (NS Proxy vs)
instance FromAvroEnum '[] where
  fromAvroEnum :: Text -> Either [Char] (NS Proxy '[])
fromAvroEnum _ = [Char] -> Either [Char] (NS Proxy '[])
forall a b. a -> Either a b
Left "enum choice not found"
instance (KnownName name, FromAvroEnum vs)
         => FromAvroEnum ('ChoiceDef name ': vs) where
  fromAvroEnum :: Text -> Either [Char] (NS Proxy ('ChoiceDef name : vs))
fromAvroEnum s :: Text
s
    | Text
s Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
fieldName = NS Proxy ('ChoiceDef name : vs)
-> Either [Char] (NS Proxy ('ChoiceDef name : vs))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NS Proxy ('ChoiceDef name : vs)
 -> Either [Char] (NS Proxy ('ChoiceDef name : vs)))
-> NS Proxy ('ChoiceDef name : vs)
-> Either [Char] (NS Proxy ('ChoiceDef name : vs))
forall a b. (a -> b) -> a -> b
$ Proxy ('ChoiceDef name) -> NS Proxy ('ChoiceDef name : vs)
forall k (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z Proxy ('ChoiceDef name)
forall k (t :: k). Proxy t
Proxy
    | Bool
otherwise      = NS Proxy vs -> NS Proxy ('ChoiceDef name : vs)
forall k (a :: k -> *) (xs :: [k]) (x :: k).
NS a xs -> NS a (x : xs)
S (NS Proxy vs -> NS Proxy ('ChoiceDef name : vs))
-> Either [Char] (NS Proxy vs)
-> Either [Char] (NS Proxy ('ChoiceDef name : vs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Either [Char] (NS Proxy vs)
forall fn (vs :: [ChoiceDef fn]).
FromAvroEnum vs =>
Text -> Either [Char] (NS Proxy vs)
fromAvroEnum Text
s
    where fieldName :: Text
fieldName = Proxy name -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy name
forall k (t :: k). Proxy t
Proxy @name)

class FromAvroUnion sch choices where
  fromAvroU :: Int -> AVal.Value -> Either String (NS (FieldValue sch) choices)
instance FromAvroUnion sch '[] where
  fromAvroU :: Int -> Value -> Either [Char] (NS (FieldValue sch) '[])
fromAvroU _ _ = [Char] -> Either [Char] (NS (FieldValue sch) '[])
forall a b. a -> Either a b
Left "union choice not found"
instance (A.FromAvro (FieldValue sch u), FromAvroUnion sch us)
         => FromAvroUnion sch (u ': us) where
  fromAvroU :: Int -> Value -> Either [Char] (NS (FieldValue sch) (u : us))
fromAvroU 0 v :: Value
v = FieldValue sch u -> NS (FieldValue sch) (u : us)
forall k (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z (FieldValue sch u -> NS (FieldValue sch) (u : us))
-> Either [Char] (FieldValue sch u)
-> Either [Char] (NS (FieldValue sch) (u : us))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (FieldValue sch u)
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
v
  fromAvroU n :: Int
n v :: Value
v = NS (FieldValue sch) us -> NS (FieldValue sch) (u : us)
forall k (a :: k -> *) (xs :: [k]) (x :: k).
NS a xs -> NS a (x : xs)
S (NS (FieldValue sch) us -> NS (FieldValue sch) (u : us))
-> Either [Char] (NS (FieldValue sch) us)
-> Either [Char] (NS (FieldValue sch) (u : us))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Value -> Either [Char] (NS (FieldValue sch) us)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (choices :: [FieldType typeName]).
FromAvroUnion sch choices =>
Int -> Value -> Either [Char] (NS (FieldValue sch) choices)
fromAvroU (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-1) Value
v

class FromAvroFields sch (fs :: [FieldDef Symbol Symbol]) where
  fromAvroF :: HM.HashMap T.Text AVal.Value
            -> Either String (NP (Field sch) fs)
instance FromAvroFields sch '[] where
  fromAvroF :: HashMap Text Value -> Either [Char] (NP (Field sch) '[])
fromAvroF _ = NP (Field sch) '[] -> Either [Char] (NP (Field sch) '[])
forall (f :: * -> *) a. Applicative f => a -> f a
pure NP (Field sch) '[]
forall k (a :: k -> *). NP a '[]
Nil
instance (KnownName name, A.FromAvro (FieldValue sch t), FromAvroFields sch fs)
         => FromAvroFields sch ('FieldDef name t ': fs) where
  fromAvroF :: HashMap Text Value
-> Either [Char] (NP (Field sch) ('FieldDef name t : fs))
fromAvroF v :: HashMap Text Value
v = case Text -> HashMap Text Value -> Maybe Value
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup Text
fieldName HashMap Text Value
v of
                  Nothing -> [Char] -> Either [Char] (NP (Field sch) ('FieldDef name t : fs))
forall a b. a -> Either a b
Left "field not found"
                  Just f :: Value
f  -> Field sch ('FieldDef name t)
-> NP (Field sch) fs -> NP (Field sch) ('FieldDef name t : fs)
forall k (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
(:*) (Field sch ('FieldDef name t)
 -> NP (Field sch) fs -> NP (Field sch) ('FieldDef name t : fs))
-> Either [Char] (Field sch ('FieldDef name t))
-> Either
     [Char]
     (NP (Field sch) fs -> NP (Field sch) ('FieldDef name t : fs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (FieldValue sch t -> Field sch ('FieldDef name t)
forall typeName fieldName (sch :: Schema typeName fieldName)
       (t :: FieldType typeName) (name :: fieldName).
FieldValue sch t -> Field sch ('FieldDef name t)
Field (FieldValue sch t -> Field sch ('FieldDef name t))
-> Either [Char] (FieldValue sch t)
-> Either [Char] (Field sch ('FieldDef name t))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Either [Char] (FieldValue sch t)
forall a. FromAvro a => Value -> Either [Char] a
AVal.fromAvro Value
f) Either
  [Char]
  (NP (Field sch) fs -> NP (Field sch) ('FieldDef name t : fs))
-> Either [Char] (NP (Field sch) fs)
-> Either [Char] (NP (Field sch) ('FieldDef name t : fs))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> HashMap Text Value -> Either [Char] (NP (Field sch) fs)
forall (sch :: Schema Symbol Symbol)
       (fs :: [FieldDef Symbol Symbol]).
FromAvroFields sch fs =>
HashMap Text Value -> Either [Char] (NP (Field sch) fs)
fromAvroF HashMap Text Value
v
    where fieldName :: Text
fieldName = Proxy name -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy name
forall k (t :: k). Proxy t
Proxy @name)

-- ToAvro instances

instance (KnownName name, ToAvroFields sch args, HasAvroSchemaFields sch args)
         => A.ToAvro (Term sch ('DRecord name args)) where
  toAvro :: Schema -> Term sch ('DRecord name args) -> Builder
toAvro s :: Schema
s@ASch.Record {} (TRecord fields :: NP (Field sch) args
fields)
    = Schema -> [(Text, Encoder)] -> Builder
A.record Schema
s ([(Text, Encoder)] -> Builder) -> [(Text, Encoder)] -> Builder
forall a b. (a -> b) -> a -> b
$ NP (Field sch) args -> [(Text, Encoder)]
forall (sch :: Schema Symbol Symbol)
       (fs :: [FieldDef Symbol Symbol]).
ToAvroFields sch fs =>
NP (Field sch) fs -> [(Text, Encoder)]
toAvroF NP (Field sch) args
fields
  -- if we don't have a record, fall back to the one from schema
  toAvro _ (TRecord fields :: NP (Field sch) args
fields)
    = Schema -> [(Text, Encoder)] -> Builder
A.record (Tagged (Term sch ('DRecord name args)) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (Term sch ('DRecord name args)) Schema -> Schema)
-> Tagged (Term sch ('DRecord name args)) Schema -> Schema
forall a b. (a -> b) -> a -> b
$ [TypeName] -> Tagged (Term sch ('DRecord name args)) Schema
forall k (x :: k).
HasAvroSchema' x =>
[TypeName] -> Tagged x Schema
schema' @(Term sch ('DRecord name args)) []) ([(Text, Encoder)] -> Builder) -> [(Text, Encoder)] -> Builder
forall a b. (a -> b) -> a -> b
$ NP (Field sch) args -> [(Text, Encoder)]
forall (sch :: Schema Symbol Symbol)
       (fs :: [FieldDef Symbol Symbol]).
ToAvroFields sch fs =>
NP (Field sch) fs -> [(Text, Encoder)]
toAvroF NP (Field sch) args
fields
instance (KnownName name, ToAvroEnum choices, HasAvroSchemaEnum choices)
          => A.ToAvro (Term sch ('DEnum name choices)) where
  toAvro :: Schema -> Term sch ('DEnum name choices) -> Builder
toAvro ASch.Enum { symbols :: Schema -> Vector Text
ASch.symbols = Vector Text
ss } (TEnum n :: NS Proxy choices
n)
    = Word8 -> Builder
word8 (Word8 -> Builder) -> Word8 -> Builder
forall a b. (a -> b) -> a -> b
$ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Vector Text -> NS Proxy choices -> Int
forall k (choices :: [k]).
ToAvroEnum choices =>
Vector Text -> NS Proxy choices -> Int
toAvroE Vector Text
ss NS Proxy choices
n
  -- otherwise fall back to the one from schema
  toAvro _ (TEnum n :: NS Proxy choices
n)
    = Word8 -> Builder
word8 (Word8 -> Builder) -> Word8 -> Builder
forall a b. (a -> b) -> a -> b
$ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Vector Text -> NS Proxy choices -> Int
forall k (choices :: [k]).
ToAvroEnum choices =>
Vector Text -> NS Proxy choices -> Int
toAvroE ([Text] -> Vector Text
forall a. [a] -> Vector a
V.fromList ([Text] -> Vector Text) -> [Text] -> Vector Text
forall a b. (a -> b) -> a -> b
$ Proxy choices -> [Text]
forall fn (fs :: [ChoiceDef fn]).
HasAvroSchemaEnum fs =>
Proxy fs -> [Text]
schemaE (Proxy choices
forall k (t :: k). Proxy t
Proxy @choices)) NS Proxy choices
n
instance (A.ToAvro (FieldValue sch t))
         => A.ToAvro (Term sch ('DSimple t)) where
  toAvro :: Schema -> Term sch ('DSimple t) -> Builder
toAvro s :: Schema
s (TSimple v :: FieldValue sch t1
v) = Schema -> FieldValue sch t1 -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s FieldValue sch t1
v

instance A.ToAvro (FieldValue sch 'TNull) where
  toAvro :: Schema -> FieldValue sch 'TNull -> Builder
toAvro _ FNull = Builder
forall a. Monoid a => a
mempty
instance A.ToAvro t => A.ToAvro (FieldValue sch ('TPrimitive t)) where
  toAvro :: Schema -> FieldValue sch ('TPrimitive t) -> Builder
toAvro s :: Schema
s (FPrimitive v :: t1
v) = Schema -> t1 -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s t1
v
instance ( KnownName t, A.ToAvro (Term sch (sch :/: t)) )
         => A.ToAvro (FieldValue sch ('TSchematic t)) where
  toAvro :: Schema -> FieldValue sch ('TSchematic t) -> Builder
toAvro s :: Schema
s (FSchematic v :: Term sch (sch :/: t1)
v) = Schema -> Term sch (sch :/: t) -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s Term sch (sch :/: t)
Term sch (sch :/: t1)
v
instance (ToAvroUnion sch choices)
         => A.ToAvro (FieldValue sch ('TUnion choices)) where
  toAvro :: Schema -> FieldValue sch ('TUnion choices) -> Builder
toAvro (ASch.Union vs :: Vector Schema
vs) (FUnion v :: NS (FieldValue sch) choices
v) = Vector Schema -> Int -> NS (FieldValue sch) choices -> Builder
forall typeName fieldName (sch :: Schema typeName fieldName)
       (choices :: [FieldType typeName]).
ToAvroUnion sch choices =>
Vector Schema -> Int -> NS (FieldValue sch) choices -> Builder
toAvroU Vector Schema
vs 0 NS (FieldValue sch) choices
v
  toAvro s :: Schema
s _                        = [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ("this should never happen:\n" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Schema -> [Char]
forall a. Show a => a -> [Char]
show Schema
s)
instance (A.ToAvro (FieldValue sch t))
         => A.ToAvro (FieldValue sch ('TOption t)) where
  toAvro :: Schema -> FieldValue sch ('TOption t) -> Builder
toAvro s :: Schema
s (FOption v :: Maybe (FieldValue sch t1)
v) = Schema -> Maybe (FieldValue sch t1) -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s Maybe (FieldValue sch t1)
v
instance (A.ToAvro (FieldValue sch t))
         => A.ToAvro (FieldValue sch ('TList t)) where
  toAvro :: Schema -> FieldValue sch ('TList t) -> Builder
toAvro s :: Schema
s (FList v :: [FieldValue sch t1]
v) = Schema -> [FieldValue sch t1] -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s [FieldValue sch t1]
v
-- These are the only two versions of Map supported by the library
instance (A.ToAvro (FieldValue sch v))
         => A.ToAvro (FieldValue sch ('TMap ('TPrimitive T.Text) v)) where
  toAvro :: Schema -> FieldValue sch ('TMap ('TPrimitive Text) v) -> Builder
toAvro s :: Schema
s (FMap v :: Map (FieldValue sch k) (FieldValue sch v)
v) = Schema -> Map Text (FieldValue sch v) -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s (Map Text (FieldValue sch v) -> Builder)
-> Map Text (FieldValue sch v) -> Builder
forall a b. (a -> b) -> a -> b
$ (FieldValue sch k -> Text)
-> Map (FieldValue sch k) (FieldValue sch v)
-> Map Text (FieldValue sch v)
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeys (\(FPrimitive k :: t1
k) -> t1
Text
k) Map (FieldValue sch k) (FieldValue sch v)
v
instance (A.ToAvro (FieldValue sch v))
         => A.ToAvro (FieldValue sch ('TMap ('TPrimitive String) v)) where
  toAvro :: Schema -> FieldValue sch ('TMap ('TPrimitive [Char]) v) -> Builder
toAvro s :: Schema
s (FMap v :: Map (FieldValue sch k) (FieldValue sch v)
v) = Schema -> Map Text (FieldValue sch v) -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
s (Map Text (FieldValue sch v) -> Builder)
-> Map Text (FieldValue sch v) -> Builder
forall a b. (a -> b) -> a -> b
$ (FieldValue sch k -> Text)
-> Map (FieldValue sch k) (FieldValue sch v)
-> Map Text (FieldValue sch v)
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeys (\(FPrimitive k :: t1
k) -> [Char] -> Text
T.pack t1
[Char]
k) Map (FieldValue sch k) (FieldValue sch v)
v

class ToAvroEnum choices where
  toAvroE :: V.Vector T.Text -> NS Proxy choices -> Int
instance ToAvroEnum '[] where
  toAvroE :: Vector Text -> NS Proxy '[] -> Int
toAvroE = [Char] -> Vector Text -> NS Proxy '[] -> Int
forall a. HasCallStack => [Char] -> a
error "ToAvro in an empty enum"
instance (KnownName u, ToAvroEnum us)
         => ToAvroEnum ('ChoiceDef u ': us) where
  toAvroE :: Vector Text -> NS Proxy ('ChoiceDef u : us) -> Int
toAvroE s :: Vector Text
s (Z _) = Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$ Proxy u -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy u
forall k (t :: k). Proxy t
Proxy @u) Text -> Vector Text -> Maybe Int
forall a. Eq a => a -> Vector a -> Maybe Int
`V.elemIndex` Vector Text
s
  toAvroE s :: Vector Text
s (S v :: NS Proxy xs
v) = Vector Text -> NS Proxy xs -> Int
forall k (choices :: [k]).
ToAvroEnum choices =>
Vector Text -> NS Proxy choices -> Int
toAvroE Vector Text
s NS Proxy xs
v

class ToAvroUnion sch choices where
  toAvroU :: V.Vector ASch.Schema
          -> Int -> NS (FieldValue sch) choices -> Builder
instance ToAvroUnion sch '[] where
  toAvroU :: Vector Schema -> Int -> NS (FieldValue sch) '[] -> Builder
toAvroU = [Char]
-> Vector Schema -> Int -> NS (FieldValue sch) '[] -> Builder
forall a. HasCallStack => [Char] -> a
error "this should never happen"
instance (A.ToAvro (FieldValue sch u), ToAvroUnion sch us)
         => ToAvroUnion sch (u ': us) where
  toAvroU :: Vector Schema -> Int -> NS (FieldValue sch) (u : us) -> Builder
toAvroU allSch :: Vector Schema
allSch n :: Int
n (Z v :: FieldValue sch x
v)
    = Int -> Vector Schema -> FieldValue sch x -> Builder
forall a. ToAvro a => Int -> Vector Schema -> a -> Builder
putIndexedValue Int
n Vector Schema
allSch FieldValue sch x
v
  toAvroU allSch :: Vector Schema
allSch n :: Int
n (S v :: NS (FieldValue sch) xs
v)
    = Vector Schema -> Int -> NS (FieldValue sch) xs -> Builder
forall typeName fieldName (sch :: Schema typeName fieldName)
       (choices :: [FieldType typeName]).
ToAvroUnion sch choices =>
Vector Schema -> Int -> NS (FieldValue sch) choices -> Builder
toAvroU Vector Schema
allSch (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+1) NS (FieldValue sch) xs
v

class ToAvroFields sch (fs :: [FieldDef Symbol Symbol]) where
  toAvroF :: NP (Field sch) fs -> [(T.Text, A.Encoder)]
instance ToAvroFields sch '[] where
  toAvroF :: NP (Field sch) '[] -> [(Text, Encoder)]
toAvroF _ = []
instance (KnownName name, A.ToAvro (FieldValue sch t), ToAvroFields sch fs)
         => ToAvroFields sch ('FieldDef name t ': fs) where
  toAvroF :: NP (Field sch) ('FieldDef name t : fs) -> [(Text, Encoder)]
toAvroF (Field v :: FieldValue sch t
v :* rest :: NP (Field sch) xs
rest) = (Text
fieldName Text -> FieldValue sch t -> (Text, Encoder)
forall a. ToAvro a => Text -> a -> (Text, Encoder)
A..= FieldValue sch t
v) (Text, Encoder) -> [(Text, Encoder)] -> [(Text, Encoder)]
forall a. a -> [a] -> [a]
: NP (Field sch) xs -> [(Text, Encoder)]
forall (sch :: Schema Symbol Symbol)
       (fs :: [FieldDef Symbol Symbol]).
ToAvroFields sch fs =>
NP (Field sch) fs -> [(Text, Encoder)]
toAvroF NP (Field sch) xs
rest
    where fieldName :: Text
fieldName  = Proxy name -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText (Proxy name
forall k (t :: k). Proxy t
Proxy @name)

-- Conversion of symbols to other things
nameText :: KnownName s => proxy s -> T.Text
nameText :: proxy s -> Text
nameText = [Char] -> Text
T.pack ([Char] -> Text) -> (proxy s -> [Char]) -> proxy s -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. proxy s -> [Char]
forall k (a :: k) (proxy :: k -> *).
KnownName a =>
proxy a -> [Char]
nameVal
nameTypeName :: KnownName s => proxy s -> ASch.TypeName
nameTypeName :: proxy s -> TypeName
nameTypeName = Text -> TypeName
ASch.parseFullname (Text -> TypeName) -> (proxy s -> Text) -> proxy s -> TypeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. proxy s -> Text
forall k (s :: k) (proxy :: k -> *). KnownName s => proxy s -> Text
nameText