use crate::{validation::Validation, AvroValue, JsonValue, Map, Record};
use serde::{de::DeserializeOwned, Serialize};
mod column;
mod context;
mod hook;
mod mutation;
mod query;
mod reference;
mod row;
mod translation;
#[doc(no_inline)]
pub use apache_avro::schema;
pub use column::{Column, EncodeColumn};
pub use context::QueryContext;
pub use hook::ModelHooks;
pub use mutation::Mutation;
pub use query::Query;
pub use reference::Reference;
pub use row::DecodeRow;
pub use translation::Translation;
pub trait Model: Default + Serialize + DeserializeOwned {
const MODEL_NAME: &'static str;
const ITEM_NAME: (&'static str, &'static str) = ("entry", "entries");
#[inline]
fn new() -> Self {
Self::default()
}
#[inline]
fn model_name() -> &'static str {
Self::MODEL_NAME
}
#[must_use]
fn read_map(&mut self, data: &Map) -> Validation {
let mut validation = Validation::new();
if data.is_empty() {
let message = format!("the `{}` model data should be nonempty", Self::MODEL_NAME);
validation.record("data", message);
}
validation
}
#[inline]
fn try_from_map(data: Map) -> Result<Self, serde_json::Error> {
serde_json::from_value(JsonValue::from(data))
}
#[inline]
fn try_from_avro_record(data: Record) -> Result<Self, apache_avro::Error> {
apache_avro::from_value(&AvroValue::Record(data))
}
#[must_use]
fn into_map(self) -> Map {
match serde_json::to_value(self) {
Ok(JsonValue::Object(map)) => map,
_ => panic!(
"the `{}` model cann't be converted to a json object",
Self::MODEL_NAME
),
}
}
#[must_use]
fn into_avro_record(self) -> Record {
match apache_avro::to_value(self) {
Ok(AvroValue::Record(record)) => record,
_ => panic!(
"the `{}` model cann't be converted to an Avro record",
Self::MODEL_NAME
),
}
}
#[inline]
fn data_item(value: impl Into<JsonValue>) -> Map {
let item_name = Self::ITEM_NAME.0;
let mut map = Map::new();
map.insert(item_name.to_owned(), value.into());
map
}
#[inline]
fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Map {
let item_name = Self::ITEM_NAME.1;
let mut map = Map::new();
map.insert(["num", item_name].join("_"), values.len().into());
map.insert(item_name.to_owned(), values.into());
map
}
}