avro_schema/schema/
se.rs

1use serde::ser::{SerializeMap, SerializeSeq};
2use serde::{Serialize, Serializer};
3
4use super::*;
5
6impl Serialize for Schema {
7    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
8    where
9        S: Serializer,
10    {
11        match self {
12            Schema::Null => serializer.serialize_str("null"),
13            Schema::Boolean => serializer.serialize_str("boolean"),
14            Schema::Int(logical) => match logical {
15                None => serializer.serialize_str("int"),
16                Some(logical) => {
17                    let mut map = serializer.serialize_map(Some(2))?;
18                    map.serialize_entry("type", "int")?;
19                    let name = match logical {
20                        IntLogical::Date => "date",
21                        IntLogical::Time => "time-millis",
22                    };
23                    map.serialize_entry("logicalType", name)?;
24                    map.end()
25                }
26            },
27            Schema::Long(logical) => match logical {
28                None => serializer.serialize_str("long"),
29                Some(logical) => {
30                    let mut map = serializer.serialize_map(Some(2))?;
31                    map.serialize_entry("type", "long")?;
32                    let name = match logical {
33                        LongLogical::Time => "time-micros",
34                        LongLogical::TimestampMillis => "timestamp-millis",
35                        LongLogical::TimestampMicros => "timestamp-micros",
36                        LongLogical::LocalTimestampMillis => "local-timestamp-millis",
37                        LongLogical::LocalTimestampMicros => "local-timestamp-micros",
38                    };
39                    map.serialize_entry("logicalType", name)?;
40                    map.end()
41                }
42            },
43            Schema::Float => serializer.serialize_str("float"),
44            Schema::Double => serializer.serialize_str("double"),
45            Schema::Bytes(logical) => match logical {
46                None => serializer.serialize_str("bytes"),
47                Some(logical) => match logical {
48                    BytesLogical::Decimal(precision, scale) => {
49                        let mut map = serializer.serialize_map(Some(4))?;
50                        map.serialize_entry("type", "bytes")?;
51                        map.serialize_entry("logicalType", "decimal")?;
52                        map.serialize_entry("precision", precision)?;
53                        if *scale > 0 {
54                            map.serialize_entry("scale", scale)?;
55                        }
56                        map.end()
57                    }
58                },
59            },
60            Schema::String(logical) => match logical {
61                None => serializer.serialize_str("string"),
62                Some(logical) => match logical {
63                    StringLogical::Uuid => {
64                        let mut map = serializer.serialize_map(Some(1))?;
65                        map.serialize_entry("type", "string")?;
66                        map.serialize_entry("logicalType", "uuid")?;
67                        map.end()
68                    }
69                },
70            },
71            Schema::Record(record) => {
72                let Record {
73                    name,
74                    namespace,
75                    doc,
76                    aliases,
77                    fields,
78                } = record;
79                let mut map = serializer.serialize_map(Some(3))?;
80                map.serialize_entry("type", "record")?;
81                map.serialize_entry("name", name)?;
82                if let Some(namespace) = namespace {
83                    map.serialize_entry("namespace", namespace)?;
84                }
85                if !aliases.is_empty() {
86                    map.serialize_entry("aliases", aliases)?;
87                }
88                if let Some(doc) = doc {
89                    map.serialize_entry("doc", doc)?;
90                }
91                map.serialize_entry("fields", fields)?;
92                map.end()
93            }
94            Schema::Enum(enum_) => {
95                let Enum {
96                    name,
97                    namespace,
98                    aliases,
99                    doc,
100                    symbols,
101                    default,
102                } = enum_;
103                let mut map = serializer.serialize_map(Some(3))?;
104                map.serialize_entry("type", "enum")?;
105                map.serialize_entry("name", name)?;
106                if let Some(namespace) = namespace {
107                    map.serialize_entry("namespace", namespace)?;
108                }
109                if !aliases.is_empty() {
110                    map.serialize_entry("aliases", aliases)?;
111                }
112                if let Some(doc) = doc {
113                    map.serialize_entry("doc", doc)?;
114                }
115                if let Some(default) = default {
116                    map.serialize_entry("default", default)?;
117                }
118                map.serialize_entry("symbols", symbols)?;
119                map.end()
120            }
121            Schema::Array(schema) => {
122                let mut map = serializer.serialize_map(Some(2))?;
123                map.serialize_entry("type", "array")?;
124                map.serialize_entry("items", schema.as_ref())?;
125                map.end()
126            }
127            Schema::Map(schema) => {
128                let mut map = serializer.serialize_map(Some(2))?;
129                map.serialize_entry("type", "map")?;
130                map.serialize_entry("values", schema.as_ref())?;
131                map.end()
132            }
133            Schema::Union(schemas) => {
134                let mut seq = serializer.serialize_seq(Some(schemas.len()))?;
135                for schema in schemas {
136                    seq.serialize_element(schema)?;
137                }
138                seq.end()
139            }
140            Schema::Fixed(fixed) => {
141                let Fixed {
142                    name,
143                    namespace,
144                    doc,
145                    aliases,
146                    size,
147                    logical,
148                } = fixed;
149
150                let mut map = serializer.serialize_map(None)?;
151                map.serialize_entry("type", "fixed")?;
152                map.serialize_entry("name", name)?;
153                if let Some(namespace) = namespace {
154                    map.serialize_entry("namespace", namespace)?;
155                }
156                if !aliases.is_empty() {
157                    map.serialize_entry("aliases", aliases)?;
158                }
159                if let Some(doc) = doc {
160                    map.serialize_entry("doc", doc)?;
161                }
162                map.serialize_entry("size", size)?;
163
164                if let Some(logical) = logical {
165                    match logical {
166                        FixedLogical::Decimal(precision, scale) => {
167                            map.serialize_entry("logicalType", "decimal")?;
168                            map.serialize_entry("precision", precision)?;
169                            if *scale > 0 {
170                                map.serialize_entry("scale", scale)?;
171                            }
172                        }
173                        FixedLogical::Duration => map.serialize_entry("logicalType", "duration")?,
174                    }
175                }
176
177                map.end()
178            }
179        }
180    }
181}
182
183impl Serialize for Field {
184    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185    where
186        S: Serializer,
187    {
188        let Field {
189            name,
190            doc,
191            schema,
192            default,
193            order,
194            aliases,
195        } = self;
196
197        let mut map = serializer.serialize_map(None)?;
198        map.serialize_entry("name", name)?;
199        if !aliases.is_empty() {
200            map.serialize_entry("aliases", aliases)?;
201        }
202        if let Some(doc) = doc {
203            map.serialize_entry("doc", doc)?;
204        }
205        if let Some(default) = default {
206            map.serialize_entry("default", default)?;
207        }
208        map.serialize_entry("type", schema)?;
209        if let Some(order) = order {
210            let order = match order {
211                Order::Ascending => "ascending",
212                Order::Descending => "descending",
213                Order::Ignore => "ignore",
214            };
215            map.serialize_entry("order", order)?;
216        }
217
218        map.end()
219    }
220}