1use serde::{Deserialize, Serialize};
3use std::fmt;
4
5pub const IDENT_PATH_DELIMITER: &str = ".";
7pub const ATTRIBUTE_ID_SOURCE: &str = "_source";
9pub const ATTRIBUTE_ID_DOC: &str = "doc";
11pub const ATTRIBUTE_ID_OPTION: &str = "option";
13pub const ATTRIBUTE_UNNAMED: &str = "_";
15
16pub struct Attributes<'a> {
18 base: std::slice::Iter<'a, Attribute>,
19}
20
21impl<'a> Iterator for Attributes<'a> {
23 type Item = &'a Attribute;
24 fn next(&mut self) -> Option<&'a Attribute> {
25 self.base.next()
26 }
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
44pub struct Attribute {
45 pub key: Ident,
47 pub values: Vec<(String, Constant)>,
49}
50
51impl Attribute {
52 pub fn new_key_only(key: &str) -> Attribute {
54 Attribute {
55 key: Ident::from(key),
56 values: Vec::new(),
57 }
58 }
59
60 pub fn new_single_value<C: Into<Constant>>(key: &str, value: C) -> Attribute {
62 Attribute {
63 key: Ident::from(key),
64 values: vec![("_".to_string(), value.into())],
65 }
66 }
67
68 pub fn new_single_kv<S: Into<String>, C: Into<Constant>>(
70 key: &str,
71 name: S,
72 value: C,
73 ) -> Attribute {
74 Attribute {
75 key: Ident::from(key),
76 values: vec![(name.into(), value.into())],
77 }
78 }
79
80 pub fn iter(&self) -> impl std::iter::Iterator<Item = &(String, Constant)> {
82 self.values.iter()
83 }
84
85 pub fn get(&self, name: &str) -> Option<&Constant> {
87 self.iter()
88 .find_map(|opt| if opt.0 == name { Some(&opt.1) } else { None })
89 }
90}
91
92pub trait HasAttributes {
94 fn attributes(&'_ self) -> Attributes<'_>;
96
97 fn get_attribute(&self, key: &str) -> Option<&Attribute> {
99 self.attributes().find(|a| a.key == key)
100 }
101}
102
103#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
109pub struct Ident {
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub namespace: Option<String>, pub name: String,
115}
116
117impl Ident {
118 pub fn new(s: &str) -> Self {
120 if let Some((ns, id)) = s.rsplit_once(IDENT_PATH_DELIMITER) {
121 Ident {
122 namespace: Some(ns.to_string()),
123 name: id.to_string(),
124 }
125 } else {
126 Ident {
127 namespace: None,
128 name: s.to_string(),
129 }
130 }
131 }
132
133 pub fn from_namespace(namespace: Option<String>, name: String) -> Self {
135 Ident { namespace, name }
136 }
137}
138
139impl From<String> for Ident {
141 fn from(s: String) -> Ident {
142 Ident::new(&s)
143 }
144}
145
146impl From<&str> for Ident {
148 fn from(s: &str) -> Ident {
149 Ident::new(s)
150 }
151}
152
153impl PartialEq<String> for Ident {
155 fn eq(&self, other: &String) -> bool {
156 &self.to_string() == other
157 }
158}
159
160impl PartialEq<Ident> for String {
162 fn eq(&self, other: &Ident) -> bool {
163 &other.to_string() == self
164 }
165}
166
167impl PartialEq<Ident> for &str {
169 fn eq(&self, other: &Ident) -> bool {
170 &other.to_string() == self
171 }
172}
173
174impl PartialEq<str> for Ident {
176 fn eq(&self, other: &str) -> bool {
177 self.to_string().as_str() == other
178 }
179}
180
181impl PartialEq<Ident> for str {
183 fn eq(&self, other: &Ident) -> bool {
184 *other == self
185 }
186}
187
188impl PartialEq<&str> for Ident {
190 fn eq(&self, other: &&str) -> bool {
191 self.to_string().as_str() == *other
192 }
193}
194
195pub type FieldNumberRange = std::ops::RangeInclusive<u32>;
197
198impl fmt::Display for Ident {
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 write!(f, "{}", &self.display())
202 }
203}
204
205impl Ident {
206 pub fn display(&self) -> String {
208 match self.namespace.as_ref() {
209 Some(ns) => format!("{}{}{}", ns, IDENT_PATH_DELIMITER, &self.name),
210 None => self.name.clone(),
211 }
212 }
213}
214
215#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
223pub enum FieldType {
224 Int8,
226
227 Int32,
229
230 Int64,
232
233 Uint8,
235
236 Uint32,
238
239 Uint64,
241
242 Bool,
244
245 String,
247
248 Bytes,
250
251 Float32,
253
254 Float64,
256
257 Datetime,
259
260 Map(Box<(FieldType, FieldType)>),
262
263 Array(Box<FieldType>),
265
266 ObjectOrEnum(Ident),
269}
270
271impl FieldType {
272 pub fn is_integer(&self) -> bool {
274 matches!(
275 *self,
276 FieldType::Uint8
277 | FieldType::Int8
278 | FieldType::Uint32
279 | FieldType::Int32
280 | FieldType::Uint64
281 | FieldType::Int64
282 )
283 }
284}
285
286#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
288pub struct Field {
289 pub name: String,
291 pub optional: bool,
293 pub typ: FieldType,
295 pub number: u32,
297 pub attributes: Vec<Attribute>,
299}
300
301impl Field {
302 pub fn default_value(&self) -> Option<Constant> {
304 if let Some(attr) = self.get_attribute("default") {
306 attr.get("value").cloned()
307 } else {
308 None
309 }
310 }
311}
312
313impl HasAttributes for Field {
314 fn attributes<'a>(&self) -> Attributes {
315 let atr = &self.attributes;
316 Attributes {
317 base: atr.iter(), }
319 }
320}
321
322#[derive(Debug, Default, Clone, Serialize, Deserialize)]
324pub struct Message {
325 pub name: Ident,
327
328 pub fields: Vec<Field>,
330
331 pub messages: Vec<Message>,
333
334 pub enums: Vec<Enumeration>,
336
337 pub attributes: Vec<Attribute>,
339 }
344
345impl Message {
346 pub fn get_field(&self, name: &str) -> Option<&Field> {
348 self.fields.iter().find(|f| f.name == name)
349 }
350}
351
352impl<'a> HasAttributes for Message {
353 fn attributes(&'_ self) -> Attributes<'_> {
354 Attributes {
355 base: self.attributes.iter(),
356 }
357 }
358}
359
360#[derive(Debug, Clone, Serialize, Deserialize)]
362pub struct EnumValue {
363 pub name: String,
365 pub number: i32,
367 pub attributes: Vec<Attribute>,
369}
370
371#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct Enumeration {
374 pub name: String,
376 pub values: Vec<EnumValue>,
378 pub attributes: Vec<Attribute>,
380}
381
382impl<'a> HasAttributes for Enumeration {
383 fn attributes(&'_ self) -> Attributes<'_> {
384 Attributes {
385 base: self.attributes.iter(),
386 }
387 }
388}
389
390#[derive(Debug, Clone, Serialize, Deserialize)]
392pub struct Method {
393 pub name: String,
395 pub input_type: Option<FieldType>,
397 pub output_type: Option<FieldType>,
399
400 pub attributes: Vec<Attribute>,
408}
409
410impl<'a> HasAttributes for Method {
411 fn attributes(&'_ self) -> Attributes<'_> {
412 Attributes {
413 base: self.attributes.iter(),
414 }
415 }
416}
417
418#[derive(Debug, Default, Clone, Serialize, Deserialize)]
420pub struct Service {
421 pub name: Ident,
423
424 pub methods: Vec<Method>,
426
427 pub attributes: Vec<Attribute>,
429
430 pub schema: Option<String>,
432
433 pub schema_id: Option<String>,
435}
436
437impl<'a> HasAttributes for Service {
438 fn attributes(&'_ self) -> Attributes<'_> {
439 Attributes {
440 base: self.attributes.iter(),
441 }
442 }
443}
444
445#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
448pub enum Constant {
449 U64(u64),
451 I64(i64),
453 F64(f64),
455 Bool(bool),
457 Ident(Ident),
459 String(String),
461 Bytes(Vec<u8>),
463}
464impl fmt::Display for Constant {
465 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
467 match self {
468 Constant::U64(v) => write!(f, "{}", v),
469 Constant::I64(v) => write!(f, "{}", v),
470 Constant::F64(v) => write!(f, "{}", crate::format::format_float(*v)),
471 Constant::Bool(v) => write!(f, "{}", v),
472 Constant::Ident(v) => write!(f, "{}", v),
473 Constant::String(v) => write!(f, "{}", v),
474 Constant::Bytes(_) => write!(f, "<bytes>"),
475 }
476 }
477}
478
479impl Constant {
480 pub fn format(&self) -> String {
482 match *self {
483 Constant::U64(u) => u.to_string(),
484 Constant::I64(i) => i.to_string(),
485 Constant::F64(f) => crate::format::format_float(f),
486 Constant::Bool(b) => b.to_string(),
487 Constant::Ident(ref i) => format!("{}", i),
488 Constant::String(ref s) => s.to_string(),
490 Constant::Bytes(_) => "<bytes>".to_string(),
491 }
492 }
493 pub fn as_string(&self) -> Option<&str> {
495 match &self {
496 Constant::String(s) => Some(crate::format::unquote(s.as_str())),
497 _ => None,
498 }
499 }
500}
501
502impl From<String> for Constant {
503 fn from(s: String) -> Constant {
504 Constant::String(s)
505 }
506}
507
508impl From<&str> for Constant {
509 fn from(s: &str) -> Constant {
510 Constant::String(s.to_string())
511 }
512}
513
514impl From<Vec<u8>> for Constant {
515 fn from(v: Vec<u8>) -> Constant {
516 Constant::Bytes(v)
517 }
518}
519
520impl From<u64> for Constant {
521 fn from(val: u64) -> Constant {
522 Constant::U64(val)
523 }
524}
525
526impl From<u32> for Constant {
527 fn from(val: u32) -> Constant {
528 Constant::U64(val as u64)
529 }
530}
531
532impl From<i64> for Constant {
533 fn from(val: i64) -> Constant {
534 Constant::I64(val)
535 }
536}
537
538impl From<i32> for Constant {
539 fn from(val: i32) -> Constant {
540 Constant::I64(val as i64)
541 }
542}
543
544#[derive(Debug, Default, Clone, Serialize, Deserialize)]
546pub struct Schema {
547 pub namespace: Ident, pub messages: Vec<Message>,
552
553 pub enums: Vec<Enumeration>,
555
556 pub services: Vec<Service>,
558
559 pub attributes: Vec<Attribute>,
561}
562
563impl<'a> HasAttributes for Schema {
564 fn attributes(&'_ self) -> Attributes<'_> {
565 Attributes {
566 base: self.attributes.iter(),
567 }
568 }
569}