///|
/// Runtime values accepted by the generic Avro datum codec.
pub(all) enum Datum {
  Null
  Boolean(Bool)
  Int(Int)
  Long(Int64)
  Float(Float)
  Double(Double)
  Bytes(Bytes)
  String(String)
  Array(Array[Datum])
  Map(Map[String, Datum])
  Record(Array[(String, Datum)])
  Enum(Int, String)
  Union(Int, Datum)
  Fixed(Bytes)
} derive(Debug, Eq)

///|
/// Binary datum codec failures.
pub(all) suberror CodecError {
  TypeMismatch(expected~ : String, actual~ : String)
  UnexpectedEof(offset~ : Int)
  InvalidEncoding(offset~ : Int, message~ : String)
  InvalidLength(offset~ : Int, length~ : Int64)
  LimitExceeded(offset~ : Int, limit~ : String)
  MissingField(field~ : String)
  TrailingData(offset~ : Int)
} derive(Debug, Eq)

///|
fn Datum::type_name(self : Datum) -> String {
  match self {
    Null => "null"
    Boolean(_) => "boolean"
    Int(_) => "int"
    Long(_) => "long"
    Float(_) => "float"
    Double(_) => "double"
    Bytes(_) => "bytes"
    String(_) => "string"
    Array(_) => "array"
    Map(_) => "map"
    Record(_) => "record"
    Enum(_, _) => "enum"
    Union(_, _) => "union"
    Fixed(_) => "fixed"
  }
}