{-# 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.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           Control.Monad.Trans.State
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.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 ReadSchema
s 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 c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\Text
k Value
v -> Text -> FieldValue -> Field
SLess.Field Text
k (Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue Value
v))
                       ((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)
        ReadSchema
_ -> [Char] -> Term
forall a. HasCallStack => [Char] -> a
error ([Char]
"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 ReadSchema
_ Int
i Text
_)
    = Int -> Term
SLess.TEnum Int
i
  toSchemalessTerm (AVal.Union ReadSchema
_ Int
_ Value
v)
    = Value -> Term
forall t. ToSchemalessTerm t => t -> Term
SLess.toSchemalessTerm Value
v
  toSchemalessTerm 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 Value
AVal.Null         = FieldValue
SLess.FNull
  toSchemalessValue (AVal.Boolean  Bool
b) = Bool -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Bool
b
  toSchemalessValue (AVal.Int    ReadSchema
_ Int32
b) = Int32 -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Int32
b
  toSchemalessValue (AVal.Long   ReadSchema
_ Int64
b) = Int64 -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Int64
b
  toSchemalessValue (AVal.Float  ReadSchema
_ Float
b) = Float -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Float
b
  toSchemalessValue (AVal.Double ReadSchema
_ Double
b) = Double -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Double
b
  toSchemalessValue (AVal.String ReadSchema
_ Text
b) = Text -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive Text
b
  toSchemalessValue (AVal.Fixed  ReadSchema
_ ByteString
b) = ByteString -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive ByteString
b
  toSchemalessValue (AVal.Bytes  ReadSchema
_ ByteString
b) = ByteString -> FieldValue
forall t. (Typeable t, Eq t, Ord t, Show t) => t -> FieldValue
SLess.FPrimitive ByteString
b
  toSchemalessValue (AVal.Array 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 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 ReadSchema
_ Int
_ Value
v)
    = Value -> FieldValue
forall t. ToSchemalessValue t => t -> FieldValue
SLess.toSchemalessValue Value
v
  toSchemalessValue r :: Value
r@(AVal.Record ReadSchema
_ Vector Value
_)
    = 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 (HasAvroSchema' (Term sch (sch :/: sty)))
         => A.HasAvroSchema (WithSchema sch sty t) where
  schema :: Tagged (WithSchema sch sty t) Schema
schema = Tagged (Term sch (sch :/: sty)) Schema
-> Tagged (WithSchema sch sty t) Schema
coerce (Tagged (Term sch (sch :/: sty)) Schema
 -> Tagged (WithSchema sch sty t) Schema)
-> Tagged (Term sch (sch :/: sty)) Schema
-> Tagged (WithSchema sch sty t) Schema
forall a b. (a -> b) -> a -> b
$ State [TypeName] (Tagged (Term sch (sch :/: sty)) Schema)
-> [TypeName] -> Tagged (Term sch (sch :/: sty)) Schema
forall s a. State s a -> s -> a
evalState (HasAvroSchema' (Term sch (sch :/: sty)) =>
State [TypeName] (Tagged (Term sch (sch :/: sty)) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(Term sch (sch :/: sty))) []
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 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)) )
         => A.ToAvro (WithSchema sch sty t) where
  toAvro :: Schema -> WithSchema sch sty t -> Builder
toAvro Schema
sch (WithSchema t
v)
    = Schema -> Term sch (sch :/: sty) -> Builder
forall a. ToAvro a => Schema -> a -> Builder
A.toAvro Schema
sch (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)

-- HasAvroSchema instances

class HasAvroSchema' x where
  schema' :: State [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 [Char]
"this should never happen"
instance HasAvroSchema' (FieldValue sch t)
         => A.HasAvroSchema (FieldValue sch t) where
  schema :: Tagged (FieldValue sch t) Schema
schema = State [TypeName] (Tagged (FieldValue sch t) Schema)
-> [TypeName] -> Tagged (FieldValue sch t) Schema
forall s a. State s a -> s -> a
evalState State [TypeName] (Tagged (FieldValue sch t) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' []

instance (KnownName name, HasAvroSchemaFields sch args)
         => HasAvroSchema' (Term sch ('DRecord name args)) where
  schema' :: State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
schema'
    = do let 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)
         Bool
visited <- ([TypeName] -> Bool) -> StateT [TypeName] Identity Bool
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (TypeName
recordName TypeName -> [TypeName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`)
         if Bool
visited
            then Tagged (Term sch ('DRecord name args)) Schema
-> State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (Term sch ('DRecord name args)) Schema
 -> State
      [TypeName] (Tagged (Term sch ('DRecord name args)) Schema))
-> Tagged (Term sch ('DRecord name args)) Schema
-> State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
forall a b. (a -> b) -> a -> b
$ 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 do ([TypeName] -> [TypeName]) -> StateT [TypeName] Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (TypeName
recordName TypeName -> [TypeName] -> [TypeName]
forall a. a -> [a] -> [a]
:)
                    [Field]
fields <- Proxy sch -> Proxy args -> State [TypeName] [Field]
forall k tn fn (sch :: k) (fs :: [FieldDef tn fn]).
HasAvroSchemaFields sch fs =>
Proxy sch -> Proxy fs -> State [TypeName] [Field]
schemaF (Proxy sch
forall k (t :: k). Proxy t
Proxy @sch) (Proxy args
forall k (t :: k). Proxy t
Proxy @args)
                    Tagged (Term sch ('DRecord name args)) Schema
-> State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (Term sch ('DRecord name args)) Schema
 -> State
      [TypeName] (Tagged (Term sch ('DRecord name args)) Schema))
-> Tagged (Term sch ('DRecord name args)) Schema
-> State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
forall a b. (a -> b) -> a -> b
$ 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
instance (KnownName name, HasAvroSchemaEnum choices)
          => HasAvroSchema' (Term sch ('DEnum name choices)) where
  schema' :: State [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema)
schema'
    = do let 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)
         Bool
visited <- ([TypeName] -> Bool) -> StateT [TypeName] Identity Bool
forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a
gets (TypeName
enumName TypeName -> [TypeName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`)
         if Bool
visited
            then Tagged (Term sch ('DEnum name choices)) Schema
-> State
     [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (Term sch ('DEnum name choices)) Schema
 -> State
      [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema))
-> Tagged (Term sch ('DEnum name choices)) Schema
-> State
     [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema)
forall a b. (a -> b) -> a -> b
$ 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 do ([TypeName] -> [TypeName]) -> StateT [TypeName] Identity ()
forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m ()
modify (TypeName
enumName TypeName -> [TypeName] -> [TypeName]
forall a. a -> [a] -> [a]
:)
                    Tagged (Term sch ('DEnum name choices)) Schema
-> State
     [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (Term sch ('DEnum name choices)) Schema
 -> State
      [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema))
-> Tagged (Term sch ('DEnum name choices)) Schema
-> State
     [TypeName] (Tagged (Term sch ('DEnum name choices)) Schema)
forall a b. (a -> b) -> a -> b
$ 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

instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (Term sch ('DSimple t)) where
  schema' :: State [TypeName] (Tagged (Term sch ('DSimple t)) Schema)
schema' = Tagged (FieldValue sch t) Schema
-> Tagged (Term sch ('DSimple t)) Schema
coerce (Tagged (FieldValue sch t) Schema
 -> Tagged (Term sch ('DSimple t)) Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
-> State [TypeName] (Tagged (Term sch ('DSimple t)) Schema)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch t) =>
StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch t)

instance HasAvroSchema' (FieldValue sch 'TNull) where
  schema' :: State [TypeName] (Tagged (FieldValue sch 'TNull) Schema)
schema' = Tagged (FieldValue sch 'TNull) Schema
-> State [TypeName] (Tagged (FieldValue sch 'TNull) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch 'TNull) Schema
 -> State [TypeName] (Tagged (FieldValue sch 'TNull) Schema))
-> Tagged (FieldValue sch 'TNull) Schema
-> State [TypeName] (Tagged (FieldValue sch 'TNull) Schema)
forall a b. (a -> b) -> a -> b
$ 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
  schema' :: State [TypeName] (Tagged (FieldValue sch ('TPrimitive t)) Schema)
schema' = Tagged (FieldValue sch ('TPrimitive t)) Schema
-> State
     [TypeName] (Tagged (FieldValue sch ('TPrimitive t)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TPrimitive t)) Schema
 -> State
      [TypeName] (Tagged (FieldValue sch ('TPrimitive t)) Schema))
-> Tagged (FieldValue sch ('TPrimitive t)) Schema
-> State
     [TypeName] (Tagged (FieldValue sch ('TPrimitive t)) Schema)
forall a b. (a -> b) -> a -> b
$ Tagged t Schema -> Tagged (FieldValue sch ('TPrimitive t)) Schema
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
  schema' :: State [TypeName] (Tagged (FieldValue sch ('TSchematic t)) Schema)
schema' = Tagged (Term sch (sch :/: t)) Schema
-> Tagged (FieldValue sch ('TSchematic t)) Schema
coerce (Tagged (Term sch (sch :/: t)) Schema
 -> Tagged (FieldValue sch ('TSchematic t)) Schema)
-> StateT
     [TypeName] Identity (Tagged (Term sch (sch :/: t)) Schema)
-> State
     [TypeName] (Tagged (FieldValue sch ('TSchematic t)) Schema)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (Term sch (sch :/: t)) =>
StateT [TypeName] Identity (Tagged (Term sch (sch :/: t)) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(Term sch (sch :/: t))
instance forall sch choices.
         HasAvroSchemaUnion (FieldValue sch) choices
         => HasAvroSchema' (FieldValue sch ('TUnion choices)) where
  schema' :: State [TypeName] (Tagged (FieldValue sch ('TUnion choices)) Schema)
schema' = do
    NonEmpty Schema
schs <- Proxy (FieldValue sch)
-> Proxy choices -> State [TypeName] (NonEmpty Schema)
forall k (f :: k -> *) (xs :: [k]).
HasAvroSchemaUnion f xs =>
Proxy f -> Proxy xs -> State [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)
    Tagged (FieldValue sch ('TUnion choices)) Schema
-> State
     [TypeName] (Tagged (FieldValue sch ('TUnion choices)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TUnion choices)) Schema
 -> State
      [TypeName] (Tagged (FieldValue sch ('TUnion choices)) Schema))
-> Tagged (FieldValue sch ('TUnion choices)) Schema
-> State
     [TypeName] (Tagged (FieldValue sch ('TUnion choices)) Schema)
forall a b. (a -> b) -> a -> b
$ 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
schs
instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (FieldValue sch ('TOption t)) where
  schema' :: State [TypeName] (Tagged (FieldValue sch ('TOption t)) Schema)
schema' = do
    Schema
iSchema <- Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch t) =>
StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch t)
    Tagged (FieldValue sch ('TOption t)) Schema
-> State [TypeName] (Tagged (FieldValue sch ('TOption t)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TOption t)) Schema
 -> State [TypeName] (Tagged (FieldValue sch ('TOption t)) Schema))
-> Tagged (FieldValue sch ('TOption t)) Schema
-> State [TypeName] (Tagged (FieldValue sch ('TOption t)) Schema)
forall a b. (a -> b) -> a -> b
$ 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]
instance HasAvroSchema' (FieldValue sch t)
         => HasAvroSchema' (FieldValue sch ('TList t)) where
  schema' :: State [TypeName] (Tagged (FieldValue sch ('TList t)) Schema)
schema' = do
    Schema
iSchema <- Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch t) =>
StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch t)
    Tagged (FieldValue sch ('TList t)) Schema
-> State [TypeName] (Tagged (FieldValue sch ('TList t)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TList t)) Schema
 -> State [TypeName] (Tagged (FieldValue sch ('TList t)) Schema))
-> Tagged (FieldValue sch ('TList t)) Schema
-> State [TypeName] (Tagged (FieldValue sch ('TList t)) Schema)
forall a b. (a -> b) -> a -> b
$ 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
-- 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
  schema' :: State
  [TypeName]
  (Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema)
schema' = do
    Schema
iSchema <- Tagged (FieldValue sch v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch v) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch v) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch v) =>
StateT [TypeName] Identity (Tagged (FieldValue sch v) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch v)
    Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
-> State
     [TypeName]
     (Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
 -> State
      [TypeName]
      (Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema))
-> Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema
-> State
     [TypeName]
     (Tagged (FieldValue sch ('TMap ('TPrimitive Text) v)) Schema)
forall a b. (a -> b) -> a -> b
$ 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
instance HasAvroSchema' (FieldValue sch v)
         => HasAvroSchema' (FieldValue sch ('TMap ('TPrimitive String) v)) where
  schema' :: State
  [TypeName]
  (Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema)
schema' = do
    Schema
iSchema <- Tagged (FieldValue sch v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch v) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch v) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch v) =>
StateT [TypeName] Identity (Tagged (FieldValue sch v) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch v)
    Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
-> State
     [TypeName]
     (Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
 -> State
      [TypeName]
      (Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema))
-> Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema
-> State
     [TypeName]
     (Tagged (FieldValue sch ('TMap ('TPrimitive [Char]) v)) Schema)
forall a b. (a -> b) -> a -> b
$ 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

class HasAvroSchemaUnion (f :: k -> *) (xs :: [k]) where
  schemaU :: Proxy f -> Proxy xs -> State [ASch.TypeName] (NonEmpty ASch.Schema)
instance HasAvroSchema' (f v) => HasAvroSchemaUnion f '[v] where
  schemaU :: Proxy f -> Proxy '[v] -> State [TypeName] (NonEmpty Schema)
schemaU Proxy f
_ Proxy '[v]
_ = do
    Schema
vSchema <- Tagged (f v) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (f v) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (f v) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (f v) =>
StateT [TypeName] Identity (Tagged (f v) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(f v)
    NonEmpty Schema -> State [TypeName] (NonEmpty Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NonEmpty Schema -> State [TypeName] (NonEmpty Schema))
-> NonEmpty Schema -> State [TypeName] (NonEmpty Schema)
forall a b. (a -> b) -> a -> b
$ Schema
vSchema Schema -> [Schema] -> NonEmpty Schema
forall a. a -> [a] -> NonEmpty a
:| []
instance (HasAvroSchema' (f x), HasAvroSchemaUnion f (y ': zs))
         => HasAvroSchemaUnion f (x ': y ': zs) where
  schemaU :: Proxy f -> Proxy (x : y : zs) -> State [TypeName] (NonEmpty Schema)
schemaU Proxy f
p Proxy (x : y : zs)
_ = do
    Schema
xSchema   <- Tagged (f x) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (f x) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (f x) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (f x) =>
StateT [TypeName] Identity (Tagged (f x) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(f x)
    NonEmpty Schema
yzsSchema <- Proxy f -> Proxy (y : zs) -> State [TypeName] (NonEmpty Schema)
forall k (f :: k -> *) (xs :: [k]).
HasAvroSchemaUnion f xs =>
Proxy f -> Proxy xs -> State [TypeName] (NonEmpty Schema)
schemaU Proxy f
p (Proxy (y : zs)
forall k (t :: k). Proxy t
Proxy @(y ': zs))
    NonEmpty Schema -> State [TypeName] (NonEmpty Schema)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NonEmpty Schema -> State [TypeName] (NonEmpty Schema))
-> NonEmpty Schema -> State [TypeName] (NonEmpty Schema)
forall a b. (a -> b) -> a -> b
$ 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

class HasAvroSchemaFields sch (fs :: [FieldDef tn fn]) where
  schemaF :: Proxy sch -> Proxy fs -> State [ASch.TypeName] [ASch.Field]
instance HasAvroSchemaFields sch '[] where
  schemaF :: Proxy sch -> Proxy '[] -> State [TypeName] [Field]
schemaF Proxy sch
_ Proxy '[]
_ = [Field] -> State [TypeName] [Field]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
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) -> State [TypeName] [Field]
schemaF Proxy sch
psch Proxy ('FieldDef name t : fs)
_ = do
    let 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)
    Schema
schemaT <- Tagged (FieldValue sch t) Schema -> Schema
forall k (s :: k) b. Tagged s b -> b
unTagged (Tagged (FieldValue sch t) Schema -> Schema)
-> StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
-> StateT [TypeName] Identity Schema
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HasAvroSchema' (FieldValue sch t) =>
StateT [TypeName] Identity (Tagged (FieldValue sch t) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(FieldValue sch t)
    let 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
    [Field]
rest <- Proxy sch -> Proxy fs -> State [TypeName] [Field]
forall k tn fn (sch :: k) (fs :: [FieldDef tn fn]).
HasAvroSchemaFields sch fs =>
Proxy sch -> Proxy fs -> State [TypeName] [Field]
schemaF Proxy sch
psch (Proxy fs
forall k (t :: k). Proxy t
Proxy @fs)
    [Field] -> State [TypeName] [Field]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Field] -> State [TypeName] [Field])
-> [Field] -> State [TypeName] [Field]
forall a b. (a -> b) -> a -> b
$ Field
schemaThis Field -> [Field] -> [Field]
forall a. a -> [a] -> [a]
: [Field]
rest

class HasAvroSchemaEnum (fs :: [ChoiceDef fn]) where
  schemaE :: Proxy fs -> [T.Text]
instance HasAvroSchemaEnum '[] where
  schemaE :: Proxy '[] -> [Text]
schemaE Proxy '[]
_ = []
instance (KnownName name, HasAvroSchemaEnum fs)
         => HasAvroSchemaEnum ('ChoiceDef name ': fs) where
  schemaE :: Proxy ('ChoiceDef name : fs) -> [Text]
schemaE Proxy ('ChoiceDef name : fs)
_ = 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 } 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 Value
_ = [Char] -> Either [Char] (Term sch ('DRecord name args))
forall a b. a -> Either a b
Left [Char]
"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 ReadSchema
_ Int
_ 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 Value
_                 = [Char] -> Either [Char] (Term sch ('DEnum name choices))
forall a b. a -> Either a b
Left [Char]
"expecting enum"
instance (A.FromAvro (FieldValue sch t))
         => A.FromAvro (Term sch ('DSimple t)) where
  fromAvro :: Value -> Either [Char] (Term sch ('DSimple t))
fromAvro 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 Value
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 Value
_         = [Char] -> Either [Char] (FieldValue sch 'TNull)
forall a b. a -> Either a b
Left [Char]
"expecting null"
instance A.FromAvro t => A.FromAvro (FieldValue sch ('TPrimitive t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TPrimitive t))
fromAvro 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 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 ReadSchema
_ Int
i 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 Value
_                  = [Char] -> Either [Char] (FieldValue sch ('TUnion choices))
forall a b. a -> Either a b
Left [Char]
"expecting union"
instance (A.FromAvro (FieldValue sch t))
         => A.FromAvro (FieldValue sch ('TOption t)) where
  fromAvro :: Value -> Either [Char] (FieldValue sch ('TOption t))
fromAvro 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 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 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 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 Text
_ = [Char] -> Either [Char] (NS Proxy '[])
forall a b. a -> Either a b
Left [Char]
"enum choice not found"
instance (KnownName name, FromAvroEnum vs)
         => FromAvroEnum ('ChoiceDef name ': vs) where
  fromAvroEnum :: Text -> Either [Char] (NS Proxy ('ChoiceDef name : vs))
fromAvroEnum 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 Int
_ Value
_ = [Char] -> Either [Char] (NS (FieldValue sch) '[])
forall a b. a -> Either a b
Left [Char]
"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 Int
0 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 Int
n 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
-Int
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 HashMap Text Value
_ = 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 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
                  Maybe Value
Nothing -> [Char] -> Either [Char] (NP (Field sch) ('FieldDef name t : fs))
forall a b. a -> Either a b
Left [Char]
"field not found"
                  Just 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 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 Schema
_ (TRecord NP (Field sch) args
fields)
    = Schema -> [(Text, Encoder)] -> Builder
A.record Schema
sch (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)
    where sch :: Schema
sch = 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
$ State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
-> [TypeName] -> Tagged (Term sch ('DRecord name args)) Schema
forall s a. State s a -> s -> a
evalState (HasAvroSchema' (Term sch ('DRecord name args)) =>
State [TypeName] (Tagged (Term sch ('DRecord name args)) Schema)
forall k (x :: k).
HasAvroSchema' x =>
State [TypeName] (Tagged x Schema)
schema' @(Term sch ('DRecord name args))) []
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 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 Schema
_ (TEnum 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 Schema
s (TSimple 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 Schema
_ FieldValue sch 'TNull
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 Schema
s (FPrimitive 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 Schema
s (FSchematic 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 Vector Schema
vs) (FUnion 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 Int
0 NS (FieldValue sch) choices
v
  toAvro Schema
s FieldValue sch ('TUnion choices)
_                        = [Char] -> Builder
forall a. HasCallStack => [Char] -> a
error ([Char]
"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 Schema
s (FOption 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 Schema
s (FList [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 Schema
s (FMap 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 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 Schema
s (FMap 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 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 [Char]
"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 Vector Text
s (Z Proxy x
_) = 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 Vector Text
s (S 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 [Char]
"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 Vector Schema
allSch Int
n (Z 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 Vector Schema
allSch Int
n (S 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
+Int
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 NP (Field sch) '[]
_ = []
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 FieldValue sch t
v :* 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