Highlights
Relations inside embedded types are complete. v0.10 let #[belongs_to] fields sit inside embedded structs and enum variants. v0.11 makes them usable end to end. A model can belong to one of several parent types through an embedded enum, callers set the relation from a model value instead of copying its key, filters compare against a model, and .include() preloads the relation:
#[derive(toasty::Embed)]
enum Owner {
Human {
#[shared(id)]
id: uuid::Uuid,
#[belongs_to(key = id)]
human: toasty::Deferred<Human>,
},
Animal {
#[shared(id)]
id: uuid::Uuid,
#[belongs_to(key = id)]
animal: toasty::Deferred<Animal>,
},
}
let object = toasty::create!(Object {
owner: Owner::Human { human: &alice },
})
.exec(&mut db)
.await?;
let objects = Object::all()
.include(Object::fields().owner().human().human())
.include(Object::fields().owner().animal().animal())
.exec(&mut db)
.await?;Loading checks the variant as well as the key, so a human and an animal with the same ID stay distinct. Toasty skips the query for variants that no loaded row uses, and non-deferred relations such as human: Human load automatically with their embed. Inverse has_many and has_one fields cannot yet pair with an embedded relation.
Read about relations inside embedded types.
MariaDB is a first-class backend. Enable the mariadb feature and connect with a mariadb:// URL. The driver uses MariaDB's native UUID columns and INSERT ... RETURNING, so batch inserts return database-generated IDs. It accepts the same connection parameters as the MySQL driver. A mysql:// URL pointed at MariaDB keeps MySQL behavior, including VARCHAR(36) UUID storage; moving an existing database to mariadb:// changes the default UUID column type and needs a schema migration.
Turso Cloud over HTTP. The Turso driver's new serverless feature (turso-serverless on toasty) connects to a Turso Cloud database over HTTP. A URL with a host selects serverless mode; a path or :memory: still opens the embedded engine. Local, sync, and serverless databases share one constructor and one credential API:
let driver = toasty_driver_turso::Turso::new("turso://my-db.aws-us-east-1.turso.io")?
.with_auth_token(token);Serverless transactions default to BEGIN CONCURRENT, and write-write conflicts surface as retryable serialization failures.
More field types and constraints. jiff::tz::TimeZone is now a supported field type with the jiff feature, stored as text (an IANA identifier, fixed offset, or POSIX TZ string). On PostgreSQL, #[unique] works on Vec<T> fields and compares the complete ordered array. Other backends reject the constraint when the schema is built. JSON setters also accept borrowed values.
Upgrade notes
Newtype accessors are named inner instead of _0. The rename removes clippy warnings that fired on user code. Update call sites:
// v0.10
User::fields().email()._0()
// v0.11
User::fields().email().inner()On update builders, _0() / set_0() become inner() / set_inner(). A newtype field inside an enum variant now maps to the column {field}_inner instead of {field}__0, so databases with such fields need a migration. Newtype embeds used directly as model fields keep their column names. See #1183.
MySQL rejects bulk inserts that need database-generated values. MySQL reports only the first auto-increment ID of a multi-row insert, and earlier releases assumed the rest were consecutive. Toasty now rejects such inserts with unsupported_feature before sending them. Bulk inserts with caller- or client-generated keys, such as UUIDs, still work. Otherwise insert records one at a time, or use MariaDB, which supports RETURNING. See #1194.
Changelog
Added
- Preload relations inside embedded types (#1228)
- Explicit support for MariaDB (#1227)
- Accept borrowed values in JSON setters (#1213)
- [breaking] Turso serverless deployments now connect over HTTP (#1211)
- Reference embedded relations with model values (#1172)
- Support
jiff::tz::TimeZoneas a model field type (#1221) - PostgreSQL support for unique Vec constraints (#1199)
- Conditional execution in query expressions (#1182)
Fixed
Deferred<T>now derivesPartialEq,Eq, andHash(#1238)- Variant-rooted includes now work on update queries (#1237)
- (turso) [breaking] Stop forcing turso's default mimalloc allocator (#1234)
- Enum fields now resolve by variant-local index correctly (#1218)
Notoperator now works in eval verify and type inference (#1214)- Allow Vec newtypes to derive
Embed(#1197) Connectnow readsmax_connectionfrom driver configuration (#1195)- Fields named
pathandfrom_pathnow work in macros (#1196) - [breaking] Batch insert no longer infers IDs on MySQL (#1194)
- PostgreSQL enum type names are now properly quoted (#1186)
- (macros) [breaking] Name a newtype's field
innerinstead of_0(#1183)
Changed
- [breaking] Generated model fields now preserve target types (#1249)