1use crate::{AvroValue, JsonValue, Map, Record, validation::Validation};
3use serde::{Serialize, de::DeserializeOwned};
4
5mod column;
6mod context;
7mod hook;
8mod mutation;
9mod order;
10mod query;
11mod reference;
12mod translation;
13
14#[doc(no_inline)]
15pub use apache_avro::schema;
16
17pub use column::Column;
18pub use context::QueryContext;
19pub use hook::ModelHooks;
20pub use mutation::Mutation;
21pub use order::QueryOrder;
22pub use query::Query;
23pub use reference::Reference;
24pub use translation::Translation;
25
26pub trait Model: Default + Serialize + DeserializeOwned {
30 const MODEL_NAME: &'static str;
32 const ITEM_NAME: (&'static str, &'static str) = ("entry", "entries");
34
35 #[inline]
37 fn new() -> Self {
38 Self::default()
39 }
40
41 #[inline]
43 fn model_name() -> &'static str {
44 Self::MODEL_NAME
45 }
46
47 #[must_use]
49 fn read_map(&mut self, data: &Map) -> Validation {
50 let mut validation = Validation::new();
51 if data.is_empty() {
52 let message = format!("`{}` model data should be nonempty", Self::MODEL_NAME);
53 validation.record("data", message);
54 }
55 validation
56 }
57
58 #[inline]
60 fn try_from_map(data: Map) -> Result<Self, serde_json::Error> {
61 serde_json::from_value(JsonValue::from(data))
62 }
63
64 #[inline]
66 fn try_from_avro_record(data: Record) -> Result<Self, apache_avro::Error> {
67 apache_avro::from_value(&AvroValue::Record(data))
68 }
69
70 #[must_use]
76 fn into_map(self) -> Map {
77 match serde_json::to_value(self) {
78 Ok(JsonValue::Object(map)) => map,
79 _ => panic!(
80 "`{}` model cann't be converted to a json object",
81 Self::MODEL_NAME
82 ),
83 }
84 }
85
86 #[must_use]
92 fn into_avro_record(self) -> Record {
93 match apache_avro::to_value(self) {
94 Ok(AvroValue::Record(record)) => record,
95 _ => panic!(
96 "`{}` model cann't be converted to an Avro record",
97 Self::MODEL_NAME
98 ),
99 }
100 }
101
102 #[inline]
104 fn data_item(value: impl Into<JsonValue>) -> Map {
105 let item_name = Self::ITEM_NAME.0;
106 let mut map = Map::new();
107 map.insert(item_name.to_owned(), value.into());
108 map
109 }
110
111 #[inline]
113 fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Map {
114 let item_name = Self::ITEM_NAME.1;
115 let mut map = Map::new();
116 map.insert(["num", item_name].join("_"), values.len().into());
117 map.insert(item_name.to_owned(), values.into());
118 map
119 }
120}