rust-eloquent 1.0.0

An Active Record ORM for Rust, inspired by Laravel's Eloquent.
Documentation
use rust_eloquent::{Eloquent, sqlx::FromRow};

#[derive(Debug, Clone, FromRow, rust_eloquent::Eloquent)]
#[eloquent(table = "users", global_scope = "active_only")]
pub struct User {
    pub id: i32,
    pub name: String,
    pub is_active: i32,
    pub votes: i32,
}

// -----------------------------------------
// LOCAL SCOPES & GLOBAL SCOPES
// -----------------------------------------
// The macro generated UserQueryBuilder. We can naturally add methods to it!
impl UserQueryBuilder {
    
    // Global Scope definition (called automatically by User::query())
    pub fn active_only(mut self) -> Self {
        self = self.where_eq("is_active", 1);
        self
    }

    // Local Scope 1
    pub fn popular(mut self) -> Self {
        self = self.where_gt("votes", 100);
        self
    }

    // Local Scope 2
    pub fn name_starts_with(mut self, prefix: &str) -> Self {
        self = self.where_like("name", format!("{}%", prefix));
        self
    }
}

#[tokio::main]
async fn main() -> Result<(), rust_eloquent::sqlx::Error> {
    let _ = std::fs::remove_file("scopes_test.db");
    std::fs::File::create("scopes_test.db").unwrap();
    Eloquent::init("sqlite://scopes_test.db").await?;
    let pool = Eloquent::pool();

    rust_eloquent::sqlx::query("
        CREATE TABLE users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            name TEXT NOT NULL,
            is_active INTEGER DEFAULT 1,
            votes INTEGER DEFAULT 0
        );
    ").execute(pool).await?;

    // Insert dummy data
    rust_eloquent::sqlx::query("INSERT INTO users (name, is_active, votes) VALUES ('Alice', 1, 150)").execute(pool).await?;
    rust_eloquent::sqlx::query("INSERT INTO users (name, is_active, votes) VALUES ('Bob', 0, 200)").execute(pool).await?;
    rust_eloquent::sqlx::query("INSERT INTO users (name, is_active, votes) VALUES ('Charlie', 1, 50)").execute(pool).await?;
    rust_eloquent::sqlx::query("INSERT INTO users (name, is_active, votes) VALUES ('Amanda', 1, 120)").execute(pool).await?;

    // 1. Query with Global Scope (Automatically filters out Bob because is_active = 0)
    let active_users = User::query().get().await?;
    println!("--- Active Users (Global Scope) ---");
    for user in active_users {
        println!("- {} (Votes: {})", user.name, user.votes);
    }
    
    // 2. Query with Global Scope + Local Scopes (Popular + Name starts with A)
    let popular_a_users = User::query().popular().name_starts_with("A").get().await?;
    println!("\n--- Popular Active Users starting with 'A' (Global + Local Scopes) ---");
    for user in popular_a_users {
        println!("- {} (Votes: {})", user.name, user.votes);
    }

    // 3. Query bypassing Global Scopes (Using raw builder)
    let all_users = UserQueryBuilder::new().get().await?;
    println!("\n--- All Users (Bypassing Global Scopes) ---");
    for user in all_users {
        println!("- {} (Active: {}, Votes: {})", user.name, user.is_active, user.votes);
    }

    Ok(())
}