use std::fmt::Debug;
use std::hash::Hash;
use crate::column::Column;
use crate::value::Value;
pub trait Entity: Send + Sync + Sized {
type Id: Debug + Clone + PartialEq + Eq + Hash + Send + Sync + Into<Value>;
fn table_name() -> &'static str;
fn id_column() -> &'static str;
fn columns() -> &'static [Column];
fn id(&self) -> Self::Id;
fn values(&self) -> Vec<Value>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::column::ColumnType;
struct TestEntity {
id: i64,
name: String,
}
impl Entity for TestEntity {
type Id = i64;
fn table_name() -> &'static str {
"test_entities"
}
fn id_column() -> &'static str {
"id"
}
fn columns() -> &'static [Column] {
static COLS: [Column; 2] = [
Column::new("id", ColumnType::Integer),
Column::new("name", ColumnType::Text),
];
&COLS
}
fn id(&self) -> Self::Id {
self.id
}
fn values(&self) -> Vec<Value> {
vec![Value::I64(self.id), Value::Text(self.name.clone())]
}
}
#[test]
fn entity_table_name() {
assert_eq!(TestEntity::table_name(), "test_entities");
}
#[test]
fn entity_id_column() {
assert_eq!(TestEntity::id_column(), "id");
}
#[test]
fn entity_columns() {
let cols = TestEntity::columns();
assert_eq!(cols.len(), 2);
assert_eq!(cols[0].name(), "id");
assert_eq!(cols[0].column_type(), ColumnType::Integer);
assert_eq!(cols[1].name(), "name");
assert_eq!(cols[1].column_type(), ColumnType::Text);
}
#[test]
fn entity_id() {
let e = TestEntity {
id: 42,
name: "Alice".into(),
};
assert_eq!(e.id(), 42);
}
#[test]
fn entity_values() {
let e = TestEntity {
id: 1,
name: "Bob".into(),
};
let vals = e.values();
assert_eq!(vals.len(), 2);
assert_eq!(vals[0], Value::I64(1));
assert_eq!(vals[1], Value::Text("Bob".into()));
}
#[test]
fn column_type_debug() {
assert_eq!(format!("{:?}", ColumnType::Text), "Text");
assert_eq!(format!("{:?}", ColumnType::Integer), "Integer");
assert_eq!(format!("{:?}", ColumnType::Uuid), "Uuid");
}
}