{%- if namespace.is_main() -%} pub mod helpers; {%- endif -%} {%- for child in namespace.namespaces().values() -%} {%- if child.is_std() %} pub mod stdlib; {%- else %} pub mod {{ child.name() }}; {%- endif %} {% endfor %} use std::borrow::Borrow; use std::fmt::{Debug, Display, Formatter}; use std::future::Future; {%- if has_date %} use chrono::NaiveDate; {%- endif %} {%- if has_datetime %} use chrono::{DateTime, Utc}; {%- endif %} {%- if has_decimal %} use bigdecimal::BigDecimal; {%- endif %} {%- if has_object_id %} use bson::oid::ObjectId; {%- endif %} use teo::prelude::{ teon, model, Model, Value, Result, Error, transaction, Request, ExtractFromRequest, ExtractFromPipelineCtx, request, pipeline, ExtractFromTransactionCtx, File, Arguments, }; use std::marker::PhantomData; use {{ super_keywords(namespace.path()) }}helpers::interface::{Interface, AsInterface, AsInterfaceRef, AsInterfaceVecRef}; {%- for child in namespace.namespaces().values() -%} {%- if !child.is_std() %} pub use {{ child.name() }}::{{ child.name()|pascalcase }}Namespace; {% endif %} {%- endfor %} {% for e in outline.enums() %} /// ## {{ e.title() }} /// /// {{ e.desc() }} #[repr(transparent)] #[derive(PartialEq, Clone, Debug)] pub struct {{ e.name() }} { inner: String, } impl {{ e.name() }} { {%- for m in e.members() %} /// ### Is {{ m.title() }} /// /// Returns true if value is {{ m.title()|wordcase }} pub fn is_{{ m.name()|snakecase }}(&self) -> bool { self.inner.as_str() == "{{ m.name() }}" } /// ### {{ m.title() }} /// /// {{ m.desc() }} pub fn {{ m.name()|snakecase }}() -> Self { Self { inner: "{{ m.name() }}".to_owned() } } {%- endfor %} } impl From<{{ e.name() }}> for Value { fn from(value: {{ e.name() }}) -> Value { Value::String(value.inner.clone()) } } impl TryFrom for {{ e.name() }} { type Error = Error; fn try_from(value: Value) -> std::result::Result { if let Some(enum_variant) = value.as_str() { Ok(match enum_variant { {%- for v in e.members() %} "{{ v.name() }}" => {{ e.name() }}::{{ v.name()|snakecase }}(), {%- endfor %} _ => Err(Error::new("cannot convert value to {{ e.name() }}"))? }) } else { Err(Error::new("cannot convert value to {{ e.name() }}")) } } } impl<'a> TryFrom<&'a Value> for &{{ e.name() }} { type Error = Error; fn try_from(value: &Value) -> std::result::Result { if let Some(enum_variant) = value.as_str() { Ok(match enum_variant { {%- for v in e.members() %} "{{ v.name() }}" => unsafe { &*(enum_variant as *const str as *const Self) }, {%- endfor %} _ => Err(Error::new("cannot convert &Value to &{{ e.name() }}"))? }) } else { Err(Error::new("cannot convert &Value to &{{ e.name() }}")) } } } impl AsInterface for {{ e.name() }} { fn from_value(value: Value) -> Result { if let Some(enum_variant) = value.as_str() { Ok(match enum_variant { {%- for v in e.members() %} "{{ v.name() }}" => {{ e.name() }}::{{ v.name()|snakecase }}(), {%- endfor %} _ => Err(Error::new("cannot convert value to {{ e.name() }}"))? }) } else { Err(Error::new("cannot convert value to {{ e.name() }}")) } } } impl AsInterfaceRef for {{ e.name() }} { fn from_value_ref(value: &Value) -> Result<&Self> { if let Some(enum_variant) = value.as_str() { Ok(match enum_variant { {%- for v in e.members() %} "{{ v.name() }}" => unsafe { &*(enum_variant as *const str as *const Self) }, {%- endfor %} _ => Err(Error::new("cannot convert &Value to &{{ e.name() }}"))? }) } else { Err(Error::new("cannot convert &Value to &{{ e.name() }}")) } } } {%- endfor %} {% for model in namespace.models().values() -%} {% if model.generate_entity() -%} /// ## {{ model.title() }} /// /// {{ model.desc() }} pub struct {{ model.name() }}Model { ctx: model::Ctx, } impl {{ model.name() }}Model { /// Find many {{ model.name()|wordcase }} objects. pub async fn find_many_objects(&self, query: impl Borrow) -> Result> { Ok(self.ctx.find_many(query.borrow()).await?) } /// Find a unique {{ model.name()|wordcase }} object. pub async fn find_unique_object(&self, query: impl Borrow) -> Result> { Ok(self.ctx.find_unique(query.borrow()).await?) } /// Find {{ model.name()|wordcase|articlize }} object. pub async fn find_first_object(&self, query: impl Borrow) -> Result> { Ok(self.ctx.find_first(query.borrow()).await?) } /// Create a new {{ model.name()|wordcase }} object. pub async fn create_object(&self, values: impl Borrow) -> Result<{{ model.name() }}> { Ok(self.ctx.create_object::<{{ model.name() }}>(values.borrow()).await?) } /// Create an empty {{ model.name()|wordcase }} object. pub async fn create_default_object(&self) -> Result<{{ model.name() }}> { Ok(self.ctx.create_object::<{{ model.name() }}>(teon!({}).borrow()).await?) } /// Count objects on {{ model.name()|wordcase }}. pub async fn count_objects(&self, query: impl Borrow) -> Result { Ok(self.ctx.count_objects(query.borrow()).await?) } /// Count fields on {{ model.name()|wordcase }}. pub async fn count_fields(&self, query: impl Borrow) -> Result<{{ model.name() }}CountAggregateResult> { Ok({{ model.name() }}CountAggregateResult::from_value(self.ctx.count_fields(query.borrow()).await?)?) } /// Aggregate on {{ model.name()|wordcase }}. pub async fn aggregate(&self, query: impl Borrow) -> Result<{{ model.name() }}AggregateResult> { Ok({{ model.name() }}AggregateResult::from_value(self.ctx.aggregate(query.borrow()).await?)?) } /// Group by on {{ model.name()|wordcase }}. pub async fn group_by(&self, query: impl Borrow) -> Result> { let values: Vec = self.ctx.group_by(query.borrow()).await?; let mut result = vec![]; for value in values.into_iter() { result.push({{ model.name() }}AggregateResult::from_value(value)?); } Ok(result) } {% if namespace.database().is_some() && namespace.database().unwrap().is_sql() %} /// Run a custom SQL clause. pub async fn sql(&self, sql: &str) -> Result> where T: TryFrom, Error: From { self.ctx.sql(sql).await } {% endif %} } #[derive(Clone)] pub struct {{ model.name() }} { inner: model::Object, } impl {{ model.name() }} { /// Whether this {{ model.name()|wordcase }} is new. pub fn is_new(&self) -> bool { self.inner.is_new() } /// Whether this {{ model.name()|wordcase }} is modified. pub fn is_modified(&self) -> bool { self.inner.is_modified() } /// Set new values to a {{ model.name()|wordcase }}. Validations and transformations are /// triggered. pub async fn set(&self, values: impl AsRef) -> Result<()> { self.inner.set_teon(values.as_ref()).await } /// Update with new values to a {{ model.name()|wordcase }}. Validations and transformations are /// not triggered. pub async fn update(&self, values: impl AsRef) -> Result<()> { self.inner.update_teon(values.as_ref()).await } /// Save this {{ model.name()|wordcase }}. pub async fn save(&self) -> Result<()> { self.inner.save().await } /// Delete this {{ model.name()|wordcase }}. pub async fn delete(&self) -> Result<()> { self.inner.delete().await } /// Convert this {{ model.name()|wordcase }} object to teon. pub async fn to_teon(&self) -> Result { self.inner.to_teon().await } {%- for field in model.fields().values() %} /// ## {{ field.title() }} /// /// {{ field.desc() }} pub fn {{ field.name()|snakecase|escape_rust }}(&self) -> Result<{{ lookup.call(field.type())? }}> { {%- if field.type().is_optional() && field.type().unwrap_optional().is_enum_variant() %} let value: Value = self.inner.get("{{ field.name() }}").unwrap(); Ok(match value { Value::Null => None, _ => Some(value.try_into()?), }) {%- else %} self.inner.get("{{ field.name() }}") {%- endif %} } /// ## {{ field.title() }} /// /// {{ field.desc() }} pub fn set_{{ field.name()|snakecase }}(&self, new_value: {{ lookup.call(field.type())? }}) -> Result<()> { {%- if field.type().is_optional() && field.type().unwrap_optional().is_enum_variant() %} self.inner.set("{{ field.name() }}", match new_value { None => Value::Null, Some(new_value) => Value::from(new_value), }) {%- else %} self.inner.set("{{ field.name() }}", new_value) {%- endif %} } {%- endfor %} {%- for field in model.relations().values() %} {%- if field.type().is_array() %} /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn {{ field.name()|snakecase|escape_rust }}(&self, find_many_input: impl AsRef) -> Result<{{ lookup.call(field.type())? }}> { let objects = self.inner.force_get_relation_objects("{{ field.name() }}", find_many_input.as_ref()).await?; Ok(objects.iter().map(|o| {{ lookup.call(field.type().unwrap_array())? }} { inner: o.clone() }).collect()) } /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn set_{{ field.name()|snakecase }}(&self, {{ field.name() }}: {{ lookup.call(field.type())? }}) { let objects = {{ field.name() }}.iter().map(|o| o.inner.clone()).collect(); self.inner.force_set_relation_objects("{{ field.name() }}", objects).await } /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn add_to_{{ field.name()|snakecase }}(&self, {{ field.name() }}: {{ lookup.call(field.type().borrow())? }}) { let objects = {{ field.name() }}.iter().map(|o| o.inner.clone()).collect(); self.inner.force_add_relation_objects("{{ field.name() }}", objects).await } /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn remove_from_{{ field.name()|snakecase }}(&self, {{ field.name() }}: {{ lookup.call(field.type().borrow())? }}) { let objects = {{ field.name() }}.iter().map(|o| o.inner.clone()).collect(); self.inner.force_remove_relation_objects("{{ field.name() }}", objects).await } {%- else %} /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn {{ field.name()|snakecase|escape_rust }}(&self) -> Result<{{ lookup.call(field.type())? }}> { let object = self.inner.force_get_relation_object("{{ field.name() }}").await?; {% if field.is_optional() %} Ok(match object { Some(object) => Some({{ lookup.call(field.type().unwrap_optional().borrow())? }} { inner: object }), None => None, }) {% else %} Ok({{ lookup.call(field.type())? }} { inner: object.unwrap() }) {% endif %} } /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn set_{{ field.name()|snakecase }}(&self, {{ field.name() }}: {{ lookup.call(field.type())? }}) { self.inner.force_set_relation_object("{{ field.name() }}", {% if !field.is_optional() %}Some({% endif %}{{ field.name() }}{% if field.is_optional() %}.map(|o| o.inner.clone()){% else %}.inner.clone(){% endif %}{% if !field.is_optional() %}){% endif %}).await } {%- endif -%} {%- endfor %} {%- for field in model.properties().values() %} {%- if field.getter().is_some() %} /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn {{ field.name()|snakecase|escape_rust }}(&self) -> Result<{{ lookup.call(field.type())? }}> { self.inner.get_property("{{ field.name() }}").await } {%- endif %} {%- if field.setter().is_some() %} /// ## {{ field.title() }} /// /// {{ field.desc() }} pub async fn set_{{ field.name()|snakecase }}(&self, new_value: {{ lookup.call(field.type())? }}) -> Result<()> { self.inner.set_property("{{ field.name() }}", new_value).await } {%- endif %} {%- endfor %} } impl From<{{ model.name() }}> for model::Object { fn from(value: {{ model.name() }}) -> Self { value.inner.clone() } } impl From for {{ model.name() }} { fn from(value: model::Object) -> Self { Self { inner: value } } } impl From<{{ model.name() }}> for Value { fn from(value: {{ model.name() }}) -> Self { Value::ModelObject(value.inner.clone()) } } impl AsInterface for {{ model.name() }} { fn from_value(value: Value) -> Result { let model_object: model::Object = value.try_into()?; Ok(Self { inner: model_object }) } } impl TryFrom for {{ model.name() }} { type Error = Error; fn try_from(value: Value) -> std::result::Result { let model_object: model::Object = value.try_into()?; Ok(Self { inner: model_object }) } } impl Debug for {{ model.name() }} { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Debug::fmt(&self.inner, f) } } impl Display for {{ model.name() }} { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.inner, f) } } impl ExtractFromPipelineCtx for {{ model.name() }} { fn extract(_: &Arguments, ctx: &pipeline::Ctx) -> Self { {{ model.name() }} { inner: ctx.object().clone(), } } } {%- endif %} {%- endfor %} {% for interface in outline.interfaces() -%} pub trait {{ interface.name() }}Trait{{ generics_declaration(interface.generic_names()) }}: Interface{{ where_generics_declaration(interface.generic_names()) }} { {%- for field in interface.fields() %} /// ## {{ field.title() }} /// /// {{ field.desc() }} fn {{ field.name()|snakecase|escape_rust }}(&self) -> {{ lookup_ref.call(fix_path(field.type().borrow(), namespace).borrow())? }} { {% if field.type().borrow().is_optional() -%}Some({%- endif -%}{{ fix_type_param(lookup.call(fix_path(field.type().unwrap_optional().borrow(), namespace).borrow())?) }}::{% if field.type().unwrap_optional().is_array() %}from_value_ref_vec{% else %}from_value_ref{% endif %}(self.inner().get("{{ field.name() }}"){%- if field.type().borrow().is_optional() -%}?{%-else-%}.unwrap(){%-endif-%}).unwrap(){% if field.type().borrow().is_optional() -%}){%- endif %} } /// ## {{ field.title() }} /// /// {{ field.desc() }} fn set_{{ field.name()|snakecase }}(&mut self, new_value: {{ lookup.call(fix_path(field.type().borrow(), namespace).borrow())? }}) { {% if field.type().is_optional() %} match new_value { Some(new_value) => { self.inner_mut().as_dictionary_mut().unwrap().insert("{{ field.name() }}".to_owned(), new_value.into()); }, None => { self.inner_mut().as_dictionary_mut().unwrap().shift_remove("{{ field.name() }}"); }, } {%- else -%} self.inner_mut().as_dictionary_mut().unwrap().insert("{{ field.name() }}".to_owned(), new_value.into()).unwrap(); {%- endif %} } {%- endfor %} } #[repr(transparent)] pub struct {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { inner: Value, phantom_data: PhantomData{{ phantom_generics(interface.generic_names()) }}, } impl{{ generics_declaration(interface.generic_names()) }} Borrow for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn borrow(&self) -> &Value { self.inner() } } impl{{ generics_declaration(interface.generic_names()) }} Borrow for &{{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn borrow(&self) -> &Value { self.inner() } } impl{{ generics_declaration(interface.generic_names()) }} Interface for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn inner(&self) -> &Value { &self.inner } fn inner_mut(&mut self) -> &mut Value { &mut self.inner } } impl{{ generics_declaration(interface.generic_names()) }} {{ interface.name() }}Trait{{ generics_declaration(interface.generic_names()) }} for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { } {% for extend in unwrap_extends(interface.extends(), namespace)? -%} impl{{ generics_declaration(interface.generic_names()) }} {{ extend }} for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { } {% endfor -%} impl{{ generics_declaration(interface.generic_names()) }} AsInterface for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn from_value(value: Value) -> Result { Ok(Self { inner: value, phantom_data: PhantomData::default() }) } } impl{{ generics_declaration(interface.generic_names()) }} From<{{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}> for Value{{ where_generics_declaration(interface.generic_names()) }} { fn from(value: {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}) -> Self { value.inner } } impl{{ generics_declaration(interface.generic_names()) }} AsInterfaceRef for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn from_value_ref(value: &Value) -> Result<&{{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}> { Ok(unsafe { &*(value as *const Value as *const {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}) }) } } impl{{ generics_declaration_a(interface.generic_names()) }} ExtractFromRequest<'a> for {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn extract(request: &'a Request) -> Self { Self::from_value(request.body_value().unwrap().clone()).unwrap() } } impl{{ generics_declaration_a(interface.generic_names()) }} ExtractFromRequest<'a> for &'a {{ interface.name() }}{{ generics_declaration(interface.generic_names()) }}{{ where_generics_declaration(interface.generic_names()) }} { fn extract(request: &'a Request) -> Self { {{ interface.name() }}{{ generics_declaration_double_colon(interface.generic_names()) }}::from_value_ref(request.body_value().unwrap()).unwrap() } } {% endfor -%} {% for path_arguments in outline.path_arguments() -%} #[repr(transparent)] pub struct {{ path_arguments.name() }} { request: Request, } impl {{ path_arguments.name() }} { {% for item in path_arguments.items() -%} pub fn {{ item|snakecase }}(&self) -> Result<&str> { Ok(self.request.captures()?.get("{{ item }}").unwrap().as_str()) } {%- endfor %} } impl<'a> ExtractFromRequest<'a> for {{ path_arguments.name() }} { fn extract(request: &'a Request) -> Self { {{ path_arguments.name() }} { request: request.clone(), } } } {% endfor -%} {%- if !namespace.is_std() -%} pub struct {% if namespace.is_main() %}Teo{% else %}{{ namespace.name()|capitalize }}Namespace{% endif %} { pub(crate) ctx: transaction::Ctx, } impl From for {% if namespace.is_main() %}Teo{% else %}{{ namespace.name()|capitalize }}Namespace{% endif %} { fn from(value: transaction::Ctx) -> Self { Self { ctx: value } } } impl {% if namespace.is_main() %}Teo{% else %}{{ namespace.name()|capitalize }}Namespace{% endif %} { {% if namespace.is_main() -%} pub async fn transaction(&self, f: F) -> Result where F: Fn(C) -> Fut, C: for <'a> From<&'a transaction::Ctx>, Fut: Future> { Ok(self.ctx.run_transaction(f).await?) } {% endif -%} {%- for model in namespace.models().values() %} pub fn {{ model.name()|snakecase }}(&self) -> {{ model.name() }}Model { {{ model.name() }}Model { ctx: self.ctx.model_ctx_for_model_at_path(&{{ format_model_path(model.path()) }}).unwrap() } } {%- endfor %} {%- for child in namespace.namespaces().values() %} {%- if !child.is_std() %} pub fn {{ child.name()|snakecase }}(&self) -> {{ child.name()|pascalcase }}Namespace { {{ child.name()|pascalcase }}Namespace { ctx: self.ctx.clone() } } {%- endif %} {%- endfor %} } {% if namespace.is_main() %} impl ExtractFromTransactionCtx for Teo { fn extract(ctx: &transaction::Ctx) -> Self { Teo { ctx: ctx.clone(), } } } impl<'a> ExtractFromRequest<'a> for Teo { fn extract(request: &'a Request) -> Self { Teo { ctx: request.transaction_ctx().clone(), } } } impl ExtractFromPipelineCtx for Teo { fn extract(_: &Arguments, ctx: &pipeline::Ctx) -> Self { Teo { ctx: ctx.transaction_ctx().clone(), } } } {% endif %} {%- endif %}