Model

Trait Model 

Source
pub trait Model {
    // Required methods
    fn table_name() -> &'static str;
    fn columns() -> Vec<ColumnInfo>;
    fn active_columns() -> Vec<&'static str>;
    fn to_map(&self) -> HashMap<String, String>;
}
Expand description

The core trait defining a Database Model (Table) in Bottle ORM.

This trait must be implemented by all structs that represent database tables. It provides methods for retrieving table metadata, column information, and converting instances to/from database format.

§Automatic Implementation

This trait is typically implemented automatically via the #[derive(Model)] procedural macro. Manual implementation is possible but not recommended.

§Required Methods

  • table_name() - Returns the table name
  • columns() - Returns column metadata
  • active_columns() - Returns column names
  • to_map() - Serializes instance to a HashMap

§Example with Derive

use bottle_orm::Model;
use uuid::Uuid;

#[derive(Model)]
struct User {
    #[orm(primary_key)]
    id: Uuid,
    username: String,
    age: i32,
}

// Now you can use:
assert_eq!(User::table_name(), "User");
assert_eq!(User::active_columns(), vec!["id", "username", "age"]);

§Example Manual Implementation

use bottle_orm::{Model, ColumnInfo};
use std::collections::HashMap;

struct CustomUser {
    id: i32,
    name: String,
}

impl Model for CustomUser {
    fn table_name() -> &'static str {
        "custom_users"
    }

    fn columns() -> Vec<ColumnInfo> {
        vec![
            ColumnInfo {
                name: "id",
                sql_type: "INTEGER",
                is_primary_key: true,
                is_nullable: false,
                create_time: false,
                update_time: false,
                unique: false,
                index: false,
                foreign_table: None,
                foreign_key: None,
            },
            ColumnInfo {
                name: "name",
                sql_type: "TEXT",
                is_primary_key: false,
                is_nullable: false,
                create_time: false,
                update_time: false,
                unique: false,
                index: false,
                foreign_table: None,
                foreign_key: None,
            },
        ]
    }

    fn active_columns() -> Vec<&'static str> {
        vec!["id", "name"]
    }

    fn to_map(&self) -> HashMap<String, String> {
        let mut map = HashMap::new();
        map.insert("id".to_string(), self.id.to_string());
        map.insert("name".to_string(), self.name.clone());
        map
    }
}

Required Methods§

Source

fn table_name() -> &'static str

Returns the table name associated with this model.

The table name is derived from the struct name and is used in all SQL queries. By default, the derive macro uses the struct name as-is, which is then converted to snake_case when generating SQL.

§Returns

A static string slice containing the table name

§Example
#[derive(Model)]
struct UserProfile {
    // ...
}

// Returns "UserProfile"
// SQL will use: "user_profile" (snake_case)
assert_eq!(UserProfile::table_name(), "UserProfile");
Source

fn columns() -> Vec<ColumnInfo>

Returns the list of column definitions for this model.

This method provides complete metadata about each column, including SQL types, constraints, and relationships. The information is used for table creation, query building, and type conversion.

§Returns

A vector of ColumnInfo structs describing each column

§Example
#[derive(Model)]
struct User {
    #[orm(primary_key)]
    id: Uuid,
    username: String,
}

let columns = User::columns();
assert_eq!(columns.len(), 2);
assert!(columns[0].is_primary_key);
assert_eq!(columns[1].sql_type, "TEXT");
Source

fn active_columns() -> Vec<&'static str>

Returns the names of active columns (struct fields).

This method returns a simple list of column names without metadata. It’s used for query building and SELECT statement generation.

§Returns

A vector of static string slices containing column names

§Example
#[derive(Model)]
struct User {
    #[orm(primary_key)]
    id: Uuid,
    username: String,
    email: String,
}

assert_eq!(
    User::active_columns(),
    vec!["id", "username", "email"]
);
Source

fn to_map(&self) -> HashMap<String, String>

Converts the model instance into a value map (Column Name → String Value).

This method serializes the model instance into a HashMap where keys are column names and values are string representations. It’s used primarily for INSERT operations.

§Returns

A HashMap mapping column names to string values

§Type Conversion

All values are converted to strings via the ToString trait:

  • Primitives: Direct conversion (e.g., 42"42")
  • UUID: Hyphenated format (e.g., "550e8400-e29b-41d4-a716-446655440000")
  • DateTime: RFC 3339 format
  • Option: Only included if Some, omitted if None
§Example
use uuid::Uuid;

#[derive(Model)]
struct User {
    #[orm(primary_key)]
    id: Uuid,
    username: String,
    age: i32,
}

let user = User {
    id: Uuid::new_v4(),
    username: "john_doe".to_string(),
    age: 25,
};

let map = user.to_map();
assert!(map.contains_key("id"));
assert_eq!(map.get("username"), Some(&"john_doe".to_string()));
assert_eq!(map.get("age"), Some(&"25".to_string()));

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§