fn serialize_bytes_with_schema()

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}"))),
        }
    }