in avro/src/ser_schema.rs [957:1041]
fn serialize_bytes_with_schema(
&mut self,
value: &[u8],
schema: &Schema,
) -> Result<usize, Error> {
let create_error = |cause: String| {
use std::fmt::Write;
let mut v_str = String::with_capacity(value.len());
for b in value {
if write!(&mut v_str, "{:x}", b).is_err() {
v_str.push_str("??");
}
}
Error::SerializeValueWithSchema {
value_type: "bytes",
value: format!("{v_str}. Cause: {cause}"),
schema: schema.clone(),
}
};
match schema {
Schema::String | Schema::Bytes | Schema::Uuid | Schema::BigDecimal => {
self.write_bytes(value)
}
Schema::Fixed(fixed_schema) => {
if value.len() == fixed_schema.size {
self.writer.write(value).map_err(Error::WriteBytes)
} else {
Err(create_error(format!("Fixed schema size ({}) does not match the value length ({})", fixed_schema.size, value.len())))
}
}
Schema::Duration => {
if value.len() == 12 {
self.writer.write(value).map_err(Error::WriteBytes)
} else {
Err(create_error(format!("Duration length must be 12! Got ({})", value.len())))
}
}
Schema::Decimal(decimal_schema) => match decimal_schema.inner.as_ref() {
Schema::Bytes => self.write_bytes(value),
Schema::Fixed(fixed_schema) => match fixed_schema.size.checked_sub(value.len()) {
Some(pad) => {
let pad_val = match value.len() {
0 => 0,
_ => value[0],
};
let padding = vec![pad_val; pad];
self.writer
.write(padding.as_slice())
.map_err(Error::WriteBytes)?;
self.writer.write(value).map_err(Error::WriteBytes)
}
None => Err(Error::CompareFixedSizes {
size: fixed_schema.size,
n: value.len(),
}),
},
unsupported => Err(create_error(format!("Decimal schema's inner should be Bytes or Fixed schema. Got: {unsupported}"))),
},
Schema::Ref { name } => {
let ref_schema = self.get_ref_schema(name)?;
self.serialize_bytes_with_schema(value, ref_schema)
}
Schema::Union(union_schema) => {
for (i, variant_schema) in union_schema.schemas.iter().enumerate() {
match variant_schema {
Schema::String
| Schema::Bytes
| Schema::Uuid
| Schema::BigDecimal
| Schema::Fixed(_)
| Schema::Duration
| Schema::Decimal(_)
| Schema::Ref { name: _ } => {
encode_int(i as i32, &mut *self.writer)?;
return self.serialize_bytes_with_schema(value, variant_schema);
}
_ => { /* skip */ }
}
}
Err(create_error(format!("Cannot find a matching String, Bytes, Uuid, BigDecimal, Fixed, Duration, Decimal or Ref schema in {union_schema:?}")))
}
unsupported => Err(create_error(format!("Expected String, Bytes, Uuid, BigDecimal, Fixed, Duration, Decimal, Ref or Union schema. Got: {unsupported}"))),
}
}