Skip to main content

update

Macro update 

Source
update!() { /* proc-macro */ }
Expand description

Expands struct-literal syntax into update-builder method chains. Returns the same builder target.update() would return — call .exec(&mut db).await? to execute the update.

§Syntax

toasty::update!(target { field: value, ... })

target is any expression that has an .update() method — a model instance, a query builder, or a scoped relation accessor.

// Instance target
toasty::update!(user { name: "Alice Smith" })
    .exec(&mut db).await?;

// Query target
toasty::update!(User::filter_by_id(id) { name: "Bob" })
    .exec(&mut db).await?;

Instance targets do not consume the binding — the macro expands to user.update(), which auto-borrows &mut user the same way the chain form does. user stays owned after the macro returns.

Value expressions are evaluated before the target is borrowed, so they may read the target’s own fields:

toasty::update!(todo { done: !todo.done }).exec(&mut db).await?;

§Field shapes

§Explicit

field: expr sets the field to expr:

toasty::update!(user {
    name: "Alice Smith",
    email: "alice.smith@example.com",
}).exec(&mut db).await?;

expr is any Rust expression. For collection fields, pass a toasty::stmt::* combinator (e.g. stmt::push("x"), stmt::apply([...])) for non-set semantics.

§Shorthand

field alone is equivalent to field: field, matching Rust struct literal shorthand:

let name = "Alice Smith";
toasty::update!(user { name }).exec(&mut db).await?;

§Method shorthand

field.combinator(args) is shorthand for field: toasty::stmt::combinator(args). Any function in toasty::stmt works; missing functions surface as ordinary “no function” errors:

// tags.push("rust") expands to tags: stmt::push("rust")
toasty::update!(article { tags.push("rust") })
    .exec(&mut db).await?;

The shorthand is one method call deep. For chained expressions, use the explicit field: expr form.

§Embedded patch

field: { sub: val, ... } partially updates an embedded struct field, leaving sub-fields not listed unchanged. Expands to stmt::apply([stmt::patch(...), ...]):

toasty::update!(doc {
    meta: { version: 2, status: "published" },
}).exec(&mut db).await?;

Sub-fields nest to arbitrary depth. To replace an embedded value wholesale, pass the typed value directly: meta: Metadata { ... }.

§Has-many insert

field: [{ ... }, ...] inserts new children of a has-many relation. Each { ... } becomes a create builder wrapped in stmt::insert(...); the whole list is wrapped in stmt::apply([...]):

toasty::update!(user {
    todos: [{ title: "buy milk" }, { title: "walk dog" }],
}).exec(&mut db).await?;

Items can also be plain expressions, mixed in with builder shorthands — useful for combining inserts and removals:

toasty::update!(user {
    todos: [{ title: "new" }, toasty::stmt::remove(&old)],
}).exec(&mut db).await?;

§Field validation

The macro emits a method call per named field on the update builder. A field name the model does not expose for update fails with the compiler’s standard “no method named …” error at the macro call site.