rustyroad 1.8.1

Rusty Road is a framework written in Rust that is based on Ruby on Rails. It is designed to provide the familiar conventions and ease of use of Ruby on Rails, while also taking advantage of the performance and efficiency of Rust.
Documentation
//! `mod.tether` generation: the row shape, its defaults, and its validation.
//!
//! The module root is the analogue of the Rust generator's struct. TetherScript has
//! no struct to declare, so a row is a map and this file holds what a struct would
//! otherwise carry for free: the column list, the seeded defaults, and the checks
//! that a struct's types would have enforced at compile time.
//!
//! It also re-exports each CRUD function, so a caller imports one module and reaches
//! every operation — the same surface `impl` blocks give the Rust model.

mod delegates;
mod shape;
mod validate;

use crate::generators::tetherscript::model::Model;

/// Renders the module root for one model.
pub fn render(model: &Model) -> String {
    let mut file = header(model);

    file.push_str(&imports());
    file.push_str(&constants(model));
    file.push_str(&shape::columns(model));
    file.push_str(&shape::new(model));
    file.push_str(&validate::render(model));
    file.push_str(&delegates::render(model));
    file.push_str(&delegates::exports(model));

    file
}

/// Renders the file's leading comment.
fn header(model: &Model) -> String {
    format!(
        "// Model for the `{}` table.\n\
         //\n\
         // Generated by `rustyroad pull`. A row is a map keyed by column name, so\n\
         // there is no type to declare; `validate` is what a struct's field types\n\
         // would otherwise have enforced, and it runs before every write.\n\n",
        model.table
    )
}

/// Renders the imports pulling in each CRUD module.
fn imports() -> String {
    "import \"./create.tether\" as create_mod\n\
     import \"./read.tether\" as read_mod\n\
     import \"./update.tether\" as update_mod\n\
     import \"./delete.tether\" as delete_mod\n\n"
        .to_string()
}

/// Renders the table name and model name constants.
///
/// The table name is a constant rather than repeated in each statement, so a rename
/// is one edit and the CRUD modules cannot drift apart.
fn constants(model: &Model) -> String {
    format!(
        "let TABLE = \"{}\"\nlet MODEL = \"{}\"\n\n",
        model.table, model.name
    )
}