Skip to content

Commit 1419508

Browse files
authored
Merge pull request #404 from sinasab/sina/diesel-support
feat: support for diesel @ 2.2
2 parents a8a8007 + f96202a commit 1419508

File tree

5 files changed

+134
-3
lines changed

5 files changed

+134
-3
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Added
1313

14+
- Support for diesel @ 2.2 ([#404])
1415
- Support for sqlx @ 0.8 ([#400])
1516
- Support for fastrlp @ 0.4 ([#401])
1617
- Added support for [`subtle`](https://docs.rs/subtle) and [`der`](https://docs.rs/der) ([#399])
@@ -23,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2324
[#399]: https://github.com/recmo/uint/pull/399
2425
[#400]: https://github.com/recmo/uint/pull/400
2526
[#401]: https://github.com/recmo/uint/pull/401
27+
[#404]: https://github.com/recmo/uint/pull/404
2628

2729
## [1.12.3] - 2024-06-03
2830

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ subtle = { version = "2.6.1", optional = true, default-features = false }
8585
bytes = { version = "1.4", optional = true }
8686
postgres-types = { version = "0.2", optional = true }
8787

88+
# diesel
89+
diesel = { version = "2.2", optional = true }
90+
8891
# sqlx
8992
sqlx-core = { version = "0.8.2", optional = true }
9093

@@ -148,6 +151,7 @@ ark-ff-04 = ["dep:ark-ff-04"]
148151
bn-rs = ["dep:bn-rs", "std"]
149152
bytemuck = ["dep:bytemuck"]
150153
der = ["dep:der", "alloc"] # TODO: also have alloc free der impls.
154+
diesel = ["dep:diesel", "std", "dep:thiserror"]
151155
fastrlp = ["dep:fastrlp-03", "alloc"]
152156
fastrlp-04 = ["dep:fastrlp-04", "alloc"]
153157
num-bigint = ["dep:num-bigint", "alloc"]

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ named feature flag.
155155
* [`num-traits`](https://docs.rs/num-traits): Implements about forty applicable traits.
156156
* [`subtle`](https://docs.rs/subtle): Implements [`Uint::bit_ct`], [`ConditionallySelectable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallySelectable.html),[`ConditionallyNegatable`](https://docs.rs/subtle/latest/subtle/trait.ConditionallyNegatable.html), [`ConstantTimeEq`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeEq.html)/[`ConstantTimeGreater`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeGreater.html)/[`ConstantTimeLess`](https://docs.rs/subtle/latest/subtle/trait.ConstantTimeLess.html).
157157
* [`der`](https://docs.rs/der): Implements [`Encode`](https://docs.rs/der/latest/der/trait.Encode.html)/[`Decode`](https://docs.rs/der/latest/der/trait.Decode.html) and [`TryFrom`]/[`From`] casting for [`Any`](https://docs.rs/der/latest/der/asn1/struct.Any.html), [`AnyRef`](https://docs.rs/der/latest/der/asn1/struct.AnyRef.html), [`Int`](https://docs.rs/der/latest/der/asn1/struct.Int.html), [`IntRef`](https://docs.rs/der/latest/der/asn1/struct.IntRef.html), [`Uint`](https://docs.rs/der/latest/der/asn1/struct.Uint.html), [`UintRef`](https://docs.rs/der/latest/der/asn1/struct.UintRef.html).
158+
* [`diesel`](https://docs.rs/diesel): Implements the [`ToSql`](https://docs.rs/diesel/latest/diesel/serialize/trait.ToSql.html) and [`FromSql`](https://docs.rs/diesel/latest/diesel/deserialize/trait.FromSql.html) traits for storing `Uint` values as byte arrays in databases supported by Diesel.
158159

159160
## Building and testing
160161

src/support/diesel.rs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//! Support for the [`diesel`](https://crates.io/crates/diesel) crate.
2+
//!
3+
//! Currently only encodes to/from a big-endian byte array.
4+
5+
#![cfg(feature = "diesel")]
6+
#![cfg_attr(docsrs, doc(cfg(feature = "diesel")))]
7+
8+
use diesel::{
9+
backend::Backend,
10+
deserialize::{FromSql, Result as DeserResult},
11+
expression::AsExpression,
12+
internal::derives::as_expression::Bound,
13+
query_builder::bind_collector::RawBytesBindCollector,
14+
serialize::{IsNull, Output, Result as SerResult, ToSql},
15+
sql_types::{Binary, Nullable, SingleValue},
16+
Queryable,
17+
};
18+
use std::io::Write;
19+
use thiserror::Error;
20+
21+
use crate::Uint;
22+
23+
#[derive(Error, Debug)]
24+
pub enum DecodeError {
25+
#[error("Value too large for target type")]
26+
Overflow,
27+
}
28+
29+
impl<const BITS: usize, const LIMBS: usize, Db> ToSql<Binary, Db> for Uint<BITS, LIMBS>
30+
where
31+
for<'c> Db: Backend<BindCollector<'c> = RawBytesBindCollector<Db>>,
32+
{
33+
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Db>) -> SerResult {
34+
out.write_all(&self.to_be_bytes_vec())?;
35+
Ok(IsNull::No)
36+
}
37+
}
38+
39+
impl<const BITS: usize, const LIMBS: usize, Db: Backend> FromSql<Binary, Db> for Uint<BITS, LIMBS>
40+
where
41+
*const [u8]: FromSql<Binary, Db>,
42+
{
43+
fn from_sql(bytes: Db::RawValue<'_>) -> DeserResult<Self> {
44+
let bytes: *const [u8] = FromSql::<Binary, Db>::from_sql(bytes)?;
45+
let bytes: &[u8] = unsafe { &*bytes };
46+
Self::try_from_be_slice(bytes).ok_or_else(|| DecodeError::Overflow.into())
47+
}
48+
}
49+
50+
// NB: the following code is expanded derive macros. They were produced by
51+
// expanding the the following code:
52+
// ```
53+
// #[derive(diesel::AsExpression, diesel::FromSqlRow)]
54+
// #[diesel(sql_type = diesel::sql_types::Binary)]
55+
// pub struct Uint<const BITS: usize, const LIMBS: usize> { .. }
56+
// ```
57+
58+
impl<'a, const BITS: usize, const LIMBS: usize> AsExpression<Binary> for &'a Uint<BITS, LIMBS> {
59+
type Expression = Bound<Binary, Self>;
60+
fn as_expression(self) -> Self::Expression {
61+
Bound::new(self)
62+
}
63+
}
64+
65+
impl<'a, const BITS: usize, const LIMBS: usize> AsExpression<Nullable<Binary>>
66+
for &'a Uint<BITS, LIMBS>
67+
{
68+
type Expression = Bound<Nullable<Binary>, Self>;
69+
fn as_expression(self) -> Self::Expression {
70+
Bound::new(self)
71+
}
72+
}
73+
74+
impl<'a, 'b, const BITS: usize, const LIMBS: usize> AsExpression<Binary>
75+
for &'b &'a Uint<BITS, LIMBS>
76+
{
77+
type Expression = Bound<Binary, Self>;
78+
fn as_expression(self) -> Self::Expression {
79+
Bound::new(self)
80+
}
81+
}
82+
83+
impl<'a, 'b, const BITS: usize, const LIMBS: usize> AsExpression<Nullable<Binary>>
84+
for &'b &'a Uint<BITS, LIMBS>
85+
{
86+
type Expression = Bound<Nullable<Binary>, Self>;
87+
fn as_expression(self) -> Self::Expression {
88+
Bound::new(self)
89+
}
90+
}
91+
92+
impl<const BITS: usize, const LIMBS: usize, Db> ToSql<Nullable<Binary>, Db> for Uint<BITS, LIMBS>
93+
where
94+
Db: Backend,
95+
Self: ToSql<Binary, Db>,
96+
{
97+
fn to_sql<'a>(&'a self, out: &mut Output<'a, '_, Db>) -> SerResult {
98+
ToSql::<Binary, Db>::to_sql(self, out)
99+
}
100+
}
101+
102+
impl<const BITS: usize, const LIMBS: usize> AsExpression<Binary> for Uint<BITS, LIMBS> {
103+
type Expression = Bound<Binary, Self>;
104+
fn as_expression(self) -> Self::Expression {
105+
Bound::new(self)
106+
}
107+
}
108+
109+
impl<const BITS: usize, const LIMBS: usize> AsExpression<Nullable<Binary>> for Uint<BITS, LIMBS> {
110+
type Expression = Bound<Nullable<Binary>, Self>;
111+
fn as_expression(self) -> Self::Expression {
112+
Bound::new(self)
113+
}
114+
}
115+
116+
impl<const BITS: usize, const LIMBS: usize, Db, St> Queryable<St, Db> for Uint<BITS, LIMBS>
117+
where
118+
Db: Backend,
119+
St: SingleValue,
120+
Self: FromSql<St, Db>,
121+
{
122+
type Row = Self;
123+
fn build(row: Self::Row) -> DeserResult<Self> {
124+
Ok(row)
125+
}
126+
}

src/support/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod ark_ff_04;
99
mod bn_rs;
1010
mod bytemuck;
1111
mod der;
12+
pub mod diesel;
1213
mod fastrlp_03;
1314
mod fastrlp_04;
1415
mod num_bigint;
@@ -44,6 +45,3 @@ mod zeroize;
4445
// * wasm-bindgen `JsValue` bigint: https://docs.rs/wasm-bindgen/latest/wasm_bindgen/struct.JsValue.html#method.bigint_from_str
4546
// or from_f64.
4647
// * Neon `JsBigInt` once it lands: https://github.com/neon-bindings/neon/pull/861
47-
48-
// More databases:
49-
// * https://crates.io/crates/diesel

0 commit comments

Comments
 (0)