一键导入
toasty-guidance
Guidance for using the Toasty async ORM crate — schema definition, CRUD, relations, queries, and transactions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Guidance for using the Toasty async ORM crate — schema definition, CRUD, relations, queries, and transactions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
[Critical] Best practice for Rust coding. Always activate this skill before authoring Rust code or answering questions about Rust.
Idiomatic patterns for writing code with formality-core (a-mir-formality). Use when writing or reviewing judgment functions, type definitions, or parser-related code in projects built on formality-core.
Always use this skill before writing any test code in the Toasty repository
| name | toasty-guidance |
| description | Guidance for using the Toasty async ORM crate — schema definition, CRUD, relations, queries, and transactions |
| crates | toasty |
| activation | always |
Toasty is an async ORM for Rust supporting SQL (SQLite, PostgreSQL, MySQL) and NoSQL (DynamoDB). It prioritizes type safety and leans into each database's capabilities rather than hiding them.
Define models with #[derive(toasty::Model)]. Mark the primary key with #[key] and auto-generated fields with #[auto] (auto-increment for integers, UUID v7 for uuid::Uuid).
#[derive(Debug, toasty::Model)]
struct User {
#[key]
#[auto]
id: i64,
#[unique]
email: String,
name: String,
#[has_many]
todos: toasty::HasMany<Todo>,
}
#[derive(Debug, toasty::Model)]
struct Todo {
#[key]
#[auto]
id: i64,
#[index]
user_id: i64,
#[belongs_to(key = user_id, references = id)]
user: toasty::BelongsTo<User>,
title: String,
}
Use #[derive(toasty::Embed)] for value types that flatten into the parent table:
#[derive(toasty::Embed)]
struct Address {
street: String,
city: String,
}
Register all models with the builder and connect:
let db = toasty::Db::builder()
.register::<User>()
.register::<Todo>()
.connect("sqlite://memory")
.await?;
Connection strings: sqlite://memory, sqlite:///path/to/db, postgresql://user:pass@host/db, mysql://user:pass@host/db, dynamodb://region.
let user = User::create()
.name("Alice")
.email("alice@example.com")
.todo(Todo::create().title("Task 1")) // nested create
.exec(&mut db)
.await?;
// By primary key (generated finder)
let user = User::get_by_id(&mut db, &id).await?;
// All records
let users = User::all().exec(&mut db).await?;
// Filter
let users = User::all()
.and(User::fields().name().eq("Alice"))
.exec(&mut db)
.await?;
// Single result
let user = User::all()
.and(User::fields().email().eq("a@b.com"))
.one()
.exec(&mut db)
.await?;
// Optional result
let user = User::all()
.and(User::fields().email().eq("a@b.com"))
.first()
.exec(&mut db)
.await?;
// Count
let n = User::all().count().exec(&mut db).await?;
user.update()
.name("Bob")
.exec(&mut db)
.await?;
User::all()
.and(User::fields().active().eq(false))
.delete()
.exec(&mut db)
.await?;
Build type-safe filters using generated field paths:
User::fields().age().gt(18)
User::fields().age().ge(21)
User::fields().name().ne("admin")
User::fields().id().is_in([1, 2, 3])
User::fields().phone().is_some()
User::fields().phone().is_none()
// Combine with boolean logic
User::fields().age().gt(18).and(User::fields().active().eq(true))
The query! macro offers a shorthand:
toasty::query!(User filter .name == "Alice" && .age > 18)
Three relation types: HasMany<T>, HasOne<T>, BelongsTo<T>.
Lazy loading (default) -- access a relation to load it on demand:
let todos = user.todos().exec(&mut db).await?;
let owner = todo.user().exec(&mut db).await?;
Eager loading -- preload with .include():
let users = User::all()
.include(User::fields().todos())
.exec(&mut db)
.await?;
Cursor-based pagination:
let page = User::all().paginate(10).exec(&mut db).await?;
for u in &page.items { /* ... */ }
if page.has_next() {
let next = page.next(&mut db).await?;
}
let mut tx = db.transaction().await?;
User::create().name("Alice").exec(&mut tx as &mut dyn toasty::Executor).await?;
tx.commit().await?;
// Drop without commit = automatic rollback
Nested transactions (savepoints) are supported via tx.transaction().await?.
Execute independent statements together:
use toasty::batch;
let (users, posts) = batch((
User::all(),
Post::all(),
)).exec(&mut db).await?;
Executor trait is implemented by both Db and Transaction -- pass &mut db or &mut tx interchangeably.Db owns a connection pool (deadpool) and is cheap to clone.db.connection().await?..get() before loading panics. Use .include() for eager loading or call the relation method to load lazily.T is the returning type, not the model (e.g., Query<List<User>> returns Vec<User>).See the LLM.txt resource within this skill for the full API reference.