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 namecolumns()- Returns column metadataactive_columns()- Returns column namesto_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§
Sourcefn table_name() -> &'static str
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");Sourcefn columns() -> Vec<ColumnInfo>
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");Sourcefn active_columns() -> Vec<&'static str>
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"]
);Sourcefn to_map(&self) -> HashMap<String, String>
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.