1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//! # Using Avro in Rust, the Serde way.
//!
//! Avro is a schema-based format, this means it requires a few extra steps to use compared to
//! a data format like JSON.
//!
//! ## Schemas
//! It's strongly recommended to derive the schemas for your types using the [`AvroSchema`] derive macro.
//! The macro uses the Serde attributes to generate a matching schema and checks that no attributes are
//! used that are incompatible with the Serde implementation in this crate. See [the trait documentation] for
//! details on how to change the generated schema.
//!
//! Alternatively, you can write your own schema. If you go down this path, it is recommended you start with
//! the schema derived by [`AvroSchema`] and then modify it to fit your needs. For more information on mapping
//! between Serde and Avro see [Avro to Serde](crate::documentation::avro_data_model_to_serde) and [Serde to Avro](crate::documentation::serde_data_model_to_avro).
//!
//! #### Performance pitfall
//! One performance pitfall with Serde is (de)serializing bytes. The implementation of [`Serialize`][`serde::Serialize`]
//! and [`Deserialize`][`serde::Deserialize`] for types as `Vec<u8>`, `&[u8]` and `Cow<[u8]>` will
//! all use the array of integers representation. This can normally be fixed using the [`serde_bytes`]
//! crate, however this crate also needs some extra information. Therefore, you need to use the
//! [`bytes`], [`bytes_opt`], [`fixed`], [`fixed_opt`], [`mod@slice`], and [`slice_opt`] modules of
//! this crate instead.
//!
//! #### Using existing schemas
//! If you have schemas that are already being used in other parts of your software stack, generating types
//! from the schema can be very useful. There is a **third-party** crate [`rsgen-avro`] that implements this.
//!
//! ## Serializing data
//! Writing data is very simple. Use [`T::get_schema()`](AvroSchema::get_schema()) to get the schema
//! for the type you want to serialize. It is recommended to keep this schema around as long as possible
//! as generating the schema is quite expensive. Then create a [`Writer`](crate::Writer) with your schema
//! and use the [`append_ser()`](crate::Writer::append_ser()) function to serialize your data.
//!
//! ## Deserializing data
//! Reading data is both simpler and more complex than writing. On the one hand, you don't need to
//! generate a schema, as the Avro file has it embedded. But you can't directly deserialize from a
//! [`Reader`](crate::Reader). Instead, you have to iterate over the [`Value`](crate::types::Value)s
//! in the reader and deserialize from those via [`from_value`].
//!
//! ## Putting it all together
//!
//! The following is an example of how to combine everything showed so far and it is meant to be a
//! quick reference of the Serde interface:
//!
//! ```
//! # use std::io::Cursor;
//! # use serde::{Serialize, Deserialize};
//! # use apache_avro::{AvroSchema, Error, Reader, Writer, serde::{from_value, to_value}};
//! #[derive(AvroSchema, Serialize, Deserialize, PartialEq, Debug)]
//! struct Foo {
//! a: i64,
//! b: String,
//! // Otherwise it will be serialized as an array of integers
//! #[avro(with)]
//! #[serde(with = "apache_avro::serde::bytes")]
//! c: Vec<u8>,
//! }
//!
//! // Creating this schema is expensive, reuse it as much as possible
//! let schema = Foo::get_schema();
//! // A writer needs the schema of the type that is going to be written
//! let mut writer = Writer::new(&schema, Vec::new())?;
//!
//! let foo = Foo {
//! a: 42,
//! b: "Hello".to_string(),
//! c: b"Data".to_vec()
//! };
//!
//! // Serialize as many items as you want.
//! writer.append_ser(&foo)?;
//! writer.append_ser(&foo)?;
//! writer.append_ser(&foo)?;
//!
//! // Always flush
//! writer.flush()?;
//! // Or consume the writer
//! let data = writer.into_inner()?;
//!
//! // The reader does not need a schema as it's included in the data
//! let reader = Reader::new(Cursor::new(data))?;
//! // The reader is an iterator
//! for result in reader {
//! let value = result?;
//! let new_foo: Foo = from_value(&value)?;
//! assert_eq!(new_foo, foo);
//! }
//! # Ok::<(), Error>(())
//! ```
//!
//! [`rsgen-avro`]: https://docs.rs/rsgen-avro/latest/rsgen_avro/
//! [the trait documentation]: AvroSchema
pub
pub
pub use from_value;
pub use ;
pub use to_value;
pub use ;
pub use get_record_fields_in_ctxt;