2个版本
0.1.1 | 2024年5月20日 |
---|---|
0.1.0 | 2024年5月20日 |
#326 在 过程宏
9KB
diesel-json-derive
注意: 这处于积极开发中。 不保证稳定性或可用性。 您可能希望使用 diesel_json。 请注意,此版本目前期望使用postgres。 欢迎提交支持其他后端的pull request。
diesel_json_derive
这是什么?这是一个过程宏,它自动为Diesel的 Jsonb
类型推导 ToSql
和 FromSql
特性。
考虑一个如下所示的表
CREATE TABLE foo (
id TEXT PRIMARY KEY,
bar JSONB NOT NULL
);
在Rust中可以表示为(无法编译!)
#[derive(Debug, Queryable, Identifiable, Insertable, AsChangeset, Selectable)]
#[diesel(table_name = crate::schema::foo)]
#[diesel(check_for_backend(diesel::pg::Pg))]
#[diesel(primary_key(id))]
struct Foo {
id: String,
bar: Bar,
}
struct Bar {
x: i32,
}
为了使 Bar
被表示为jsonb blob,您需要实现 diesel::deserialize::FromSql
和 diesel::deserialize::FromSql
特性,例如如下所示
impl ToSql<Jsonb, Pg> for Foo {
fn to_sql<'b>(&'b self, out: &mut serialize::Output<'b, '_, Pg>) -> serialize::Result {
out.write_all(&[1])?;
serde_json::to_writer(out, &self)?;
Ok(serialize::IsNull::No)
}
}
impl FromSql<Jsonb, Pg> for Foo {
fn from_sql(bytes: PgValue<'_>) -> deserialize::Result<Self> {
let bytes = bytes.as_bytes();
if bytes[0] != 1 {
return Err("Unsupported JSONB encoding version".into());
}
serde_json::from_slice(&bytes[1..]).map_err(|_| "Invalid Json".into())
}
}
这很快变得单调乏味,因此这个crate为您完成了这项工作。因此,使用这个crate,您可以编写
use diesel::sql_types::Jsonb;
use diesel::{FromSqlRow, AsExpression};
use diesel_json_derive::DieselJsonb;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, DieselJsonb)]
#[diesel(sql_type = Jsonb)]
struct Bar {
x: i32,
}
diesel_json_derive 与 ## diesel_json
diesel_json crate 解决了相同的问题,但它使用一个包装类型。这的缺点是,当进行匹配时,需要使用这种类型。这个crate没有这个缺点。
许可证:MIT
依赖
~300–750KB
~18K SLoC