mod inputs;
mod nullable;
#[cfg(test)]
mod tests;
#[cfg(test)]
mod validate_tests;
use crate::schema::{Column, Table, mentions_generated_type};
use self::inputs::{render_insert_input, render_update_patch};
use super::{
DeriveOptions, HEADER, doc_name, keys, push_derives, push_doc, serde_derives, use_paths,
};
pub use self::nullable::render_nullable;
fn column_doc(column: &Column) -> String {
format!("The {} column.", doc_name(&column.sql_name))
}
pub fn render(table: &Table, derives: DeriveOptions) -> String {
let mut output = format!("{HEADER}\n");
let mut imports = keys::id_imports(table, &table.columns, true);
if table.columns.iter().any(|column| {
mentions_generated_type(&column.rust_type)
&& column
.typed_id
.as_ref()
.is_none_or(|id| id.module == table.module_name)
}) {
imports.push("super::super::types".to_owned());
}
if !imports.is_empty() {
output.push_str(&use_paths(&imports));
output.push('\n');
}
keys::render_key_type(&mut output, table, derives);
render_row(&mut output, table, derives.serde);
keys::render_row_key(&mut output, table);
let insert_columns = table.insert_columns();
if !insert_columns.is_empty() {
render_insert_input(&mut output, table, &insert_columns, derives);
}
let mut update_columns = table.update_columns();
if !table.primary_key.is_empty() && !update_columns.is_empty() {
render_update_patch(&mut output, table, &update_columns, derives);
} else {
update_columns.clear();
}
if derives.validate {
let fields = insert_columns.into_iter().chain(update_columns);
super::validate::push_decimal_checks(&mut output, fields);
}
output
}
fn render_row(output: &mut String, table: &Table, serde: bool) {
let doc = format!("A row of the `{}` table.", table.display_name());
push_doc(output, 0, &[&doc]);
output.push_str("#[derive(Debug, Clone, PartialEq, sqlx::FromRow)]\n");
push_derives(output, serde_derives(serde));
output.push_str(&format!("pub struct {} {{\n", table.struct_name));
for column in &table.columns {
push_doc(output, 4, &[&column_doc(column)]);
if column.rust_name != column.sql_name {
output.push_str(&format!(
" #[sqlx(rename = {})]\n",
super::sql::str_literal(&column.sql_name)
));
}
output.push_str(&format!(
" pub {}: {},\n",
column.rust_name,
column.field_type()
));
}
output.push_str("}\n");
}