Kriskras99 commented on code in PR #499:
URL: https://github.com/apache/avro-rs/pull/499#discussion_r2882794577
##########
avro/src/writer/datum.rs:
##########
@@ -15,28 +15,123 @@
// specific language governing permissions and limitations
// under the License.
-use std::io::Write;
-
+use bon::bon;
use serde::Serialize;
+use std::io::Write;
use crate::{
AvroResult, Schema,
- encode::{encode, encode_internal},
+ encode::encode_internal,
error::Details,
- schema::{NamesRef, ResolvedOwnedSchema, ResolvedSchema},
+ schema::{NamesRef, ResolvedSchema},
serde::ser_schema::SchemaAwareWriteSerializer,
types::Value,
};
+pub struct GenericDatumWriter<'s> {
+ schema: &'s Schema,
+ resolved: ResolvedSchema<'s>,
+ validate: bool,
+}
+
+#[bon]
+impl<'s> GenericDatumWriter<'s> {
+ #[builder]
+ pub fn new(
+ #[builder(start_fn)] schema: &'s Schema,
+ resolved_schemata: Option<ResolvedSchema<'s>>,
+ #[builder(default = true)] validate: bool,
+ ) -> AvroResult<Self> {
+ let resolved = if let Some(resolved) = resolved_schemata {
+ resolved
+ } else {
+ ResolvedSchema::try_from(schema)?
+ };
+ Ok(Self {
+ schema,
+ resolved,
+ validate,
+ })
+ }
+}
+
+impl<'s, S: generic_datum_writer_builder::State> GenericDatumWriterBuilder<'s,
S> {
+ /// Set the schemata that will be used to resolve any references in the
schema.
+ ///
+ /// This is equivalent to
`.resolved_schemata(ResolvedSchema::new_with_schemata(schemata)?)`.
+ /// If you already have a [`ResolvedSchema`], use that function instead.
+ pub fn schemata(
+ self,
+ schemata: Vec<&'s Schema>,
+ ) -> AvroResult<
+ GenericDatumWriterBuilder<'s,
generic_datum_writer_builder::SetResolvedSchemata<S>>,
+ >
+ where
+ S::ResolvedSchemata: generic_datum_writer_builder::IsUnset,
+ {
+ let resolved = ResolvedSchema::new_with_schemata(schemata)?;
+ Ok(self.resolved_schemata(resolved))
+ }
+}
+
+impl GenericDatumWriter<'_> {
+ /// Write a value to the writer.
+ pub fn write_value<W: Write, V: Into<Value>>(
+ &self,
+ writer: &mut W,
+ value: V,
+ ) -> AvroResult<usize> {
+ let value = value.into();
+ self.write_value_ref(writer, &value)
+ }
+
+ pub fn write_value_ref<W: Write>(&self, writer: &mut W, value: &Value) ->
AvroResult<usize> {
+ if self.validate
+ && self.resolved.get_schemata().iter().all(|s| {
+ value
+ .validate_internal(s, self.resolved.get_names(), None)
+ .is_some()
+ })
+ {
+ return Err(Details::Validation.into());
+ }
+ encode_internal(value, self.schema, self.resolved.get_names(), None,
writer)
+ }
+
+ /// Write a value to a [`Vec`].
+ pub fn write_value_to_vec<V: Into<Value>>(&self, value: V) ->
AvroResult<Vec<u8>> {
+ let mut vec = Vec::new();
+ self.write_value(&mut vec, value)?;
+ Ok(vec)
+ }
+
+ pub fn write_ser<W: Write, T: Serialize>(
+ &self,
+ writer: &mut W,
+ value: &T,
+ ) -> AvroResult<usize> {
+ let mut serializer =
+ SchemaAwareWriteSerializer::new(writer, self.schema,
self.resolved.get_names(), None);
Review Comment:
I've added a fix for `Value::validate_schemata` that does not set the
`enclosing_namespace`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]