use serde::{Deserialize, Serialize};
use vantage_table::mocks::MockTableSource;
use vantage_table::prelude::*;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub struct Bakery {
pub name: String,
pub profit_margin: f64,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub struct Client {
pub name: String,
pub email: String,
pub contact_details: String,
pub is_paying_client: bool,
pub bakery_id: i64,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
pub struct Order {
pub order_ref: String,
pub client_id: i64,
pub total: f64,
}
impl Bakery {
pub fn table(ds: MockTableSource) -> Table<MockTableSource, Bakery> {
Table::new("bakery", ds).into_entity::<Bakery>()
}
}
impl Client {
pub fn table(ds: MockTableSource) -> Table<MockTableSource, Client> {
Table::new("client", ds)
.into_entity::<Client>()
.with_one("bakery", "bakery_id", Bakery::table)
.with_many("orders", "client_id", Order::table)
}
}
impl Order {
pub fn table(ds: MockTableSource) -> Table<MockTableSource, Order> {
Table::new("order", ds)
.into_entity::<Order>()
.with_one("client", "client_id", Client::table)
}
}
pub trait ClientTable {
fn ref_bakery(&self) -> Table<MockTableSource, Bakery>;
fn ref_orders(&self) -> Table<MockTableSource, Order>;
}
impl ClientTable for Table<MockTableSource, Client> {
fn ref_bakery(&self) -> Table<MockTableSource, Bakery> {
self.get_ref_as("bakery").unwrap()
}
fn ref_orders(&self) -> Table<MockTableSource, Order> {
self.get_ref_as("orders").unwrap()
}
}
fn main() {
let ds = MockTableSource::new();
let clients = Client::table(ds.clone());
println!("=== Vantage 0.3 References Example ===\n");
println!("1. Using trait methods:");
let bakery = clients.ref_bakery();
println!(" - Got bakery table: {}", bakery.table_name());
let orders = clients.ref_orders();
println!(" - Got orders table: {}", orders.table_name());
println!("\n2. Using get_ref (returns AnyTable):");
let bakery_any = clients.get_ref("bakery").unwrap();
println!(" - DataSource: {}", bakery_any.datasource_name());
println!(" - Entity: {}", bakery_any.entity_name());
println!("\n3. Manual downcasting:");
let bakery_typed: Table<MockTableSource, Bakery> = bakery_any.downcast().unwrap();
println!(" - Successfully downcast to Table<MockTableSource, Bakery>");
println!(" - Table name: {}", bakery_typed.table_name());
println!("\n4. Chaining references:");
let order_table = Order::table(ds.clone());
let _client_from_order = order_table.ref_bakery(); println!(" - Traversed: order -> client -> bakery");
println!("\n5. Type safety:");
println!(" - Type of 'bakery': Table<MockTableSource, Bakery>");
println!(" - Type of 'orders': Table<MockTableSource, Order>");
println!(" - All type information preserved!");
println!("\n=== Key Differences from 0.2 ===");
println!("✓ No Box<dyn SqlTable> - uses AnyTable instead");
println!("✓ Works with any TableSource (not just SQL)");
println!("✓ get_ref_as() provides automatic downcasting");
println!("✓ Better error messages with type names");
println!("✓ Same ergonomic API as 0.2");
println!("\n=== TODO for Full 0.3 Implementation ===");
println!("⏳ Add condition application (IN subquery, equality)");
println!("⏳ Implement get_linked_table for JOINs");
println!("⏳ Add field importing (with_imported_fields)");
println!("⏳ Support for get_subquery_as");
}
pub trait OrderTable {
fn ref_bakery(&self) -> Table<MockTableSource, Bakery>;
fn ref_client(&self) -> Table<MockTableSource, Client>;
}
impl OrderTable for Table<MockTableSource, Order> {
fn ref_client(&self) -> Table<MockTableSource, Client> {
self.get_ref_as("client").unwrap()
}
fn ref_bakery(&self) -> Table<MockTableSource, Bakery> {
self.ref_client().ref_bakery()
}
}