Databases
vld-diesel validates a value against a vld schema before Diesel writes it, and provides column wrappers that derive AsExpression / FromSqlRow, so they work in #[derive(Insertable, Queryable)] structs and in .filter(col.eq(wrapper)).
Install
Cargo.toml
[dependencies]
vld = "0.5"
vld-diesel = "0.5" # SQLite backend by default
diesel = { version = "2", features = ["sqlite"] }
Features
| Feature | Default | Effect |
|---|---|---|
sqlite | yes | Diesel SQLite backend |
postgres | Diesel Postgres backend | |
mysql | Diesel MySQL backend |
Backends are additive. MSRV: 1.85 (see MSRV).
Example
use diesel::prelude::*;
use vld_diesel::prelude::*;
vld::schema! {
#[derive(Debug)]
pub struct NewUserSchema {
pub name: String => vld::string().min(1).max(100),
pub email: String => vld::string().email(),
pub age: i64 => vld::number().int().min(0).max(150),
}
}
diesel::table! {
users (id) {
id -> Integer,
name -> Text,
email -> Text,
age -> BigInt,
}
}
#[derive(Debug, Insertable, serde::Serialize)]
#[diesel(table_name = users)]
struct NewUser { name: String, email: String, age: i64 }
fn insert(conn: &mut SqliteConnection) -> Result<(), Box<dyn std::error::Error>> {
let user = NewUser { name: "Bob".into(), email: "bob@example.com".into(), age: 25 };
let validated = Validated::<NewUserSchema, _>::new(user)?;
diesel::insert_into(users::table)
.values(validated.inner())
.execute(conn)?;
Ok(())
}
API
validate_insert::<S, T>(&value)— serializevalueto JSON and validate it against schema typeS.validate_row::<S, T>(&row)— the same check for a loaded row.Validated<S, T>—Validated::new(value)validates and wraps;inner(),into_inner(),Deref, transparentSerialize.VldText<S>(Text),VldInt<S>(BigInt,Integer),VldFloat<S>(Double,Float),VldBool<S>(Bool) — column wrappers withToSql/FromSql;new()validates,new_unchecked()does not.VldDieselError—Validation(VldError)orSerialization(String).prelude— all of the above plusvld::prelude::*.
Gotchas
- Column schemas need a
valuefield: a wrapper validates{"value": v}againstS. FromSqldoes not re-validate: loaded values are wrapped withnew_unchecked. Usevalidate_rowto re-check.VldInton anIntegercolumn andVldFloaton aFloatcolumn narrow on write (per backend) and fail instead of truncating when the value does not fiti32/f32. ReadingFloatwidens through the decimal form (0.1stays0.1).Validated<S, T>stores the originalT: schema transforms and defaults are not applied to it.