Skip to content

Commit

Permalink
Merge pull request #66 from Selion05/master
Browse files Browse the repository at this point in the history
ulid-rs#64: add postgres traits
  • Loading branch information
dylanhart authored Sep 11, 2023
2 parents f5c3699 + 714e93b commit c09818d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ repository = "https://github.com/dylanhart/ulid-rs"
[features]
default = ["std"]
std = ["rand"]
postgres = ["dep:postgres-types", "dep:bytes"]

[dependencies]
serde = { version = "1.0", optional = true }
rand = { version = "0.8", optional = true }
uuid = { version = "1.1", optional = true }
postgres-types = { version = "0.2.6", optional = true }
bytes = { version = "1.4.0", optional = true }

[dev-dependencies]
bencher = "0.1"
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct ReadMeDoctest;
mod base32;
#[cfg(feature = "std")]
mod generator;
#[cfg(feature = "postgres")]
mod postgres;
#[cfg(feature = "serde")]
pub mod serde;
#[cfg(feature = "std")]
Expand Down
54 changes: 54 additions & 0 deletions src/postgres.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::Ulid;
use bytes::BufMut;
use bytes::BytesMut;
use postgres_types::accepts;
use postgres_types::to_sql_checked;
use postgres_types::{FromSql, IsNull, ToSql, Type};
use std::error::Error;
use std::u128;

impl FromSql<'_> for Ulid {
fn from_sql(_ty: &Type, raw: &[u8]) -> Result<Self, Box<dyn Error + Sync + Send>> {
if raw.len() != 16 {
return Err("invalid message length: uuid size mismatch".into());
}
let mut bytes = [0; 16];
bytes.copy_from_slice(raw);
Ok(Ulid(u128::from_be_bytes(bytes)))
}
accepts!(UUID);
}

impl ToSql for Ulid {
fn to_sql(&self, _: &Type, w: &mut BytesMut) -> Result<IsNull, Box<dyn Error + Sync + Send>> {
let bytes: u128 = self.0.into();
w.put_slice(&bytes.to_be_bytes());
Ok(IsNull::No)
}

accepts!(UUID);
to_sql_checked!();
}

#[cfg(test)]
mod tests {
use super::*;
use crate::Ulid;
use postgres_types::{FromSql, Type};
use std::io::Read;

#[test]
fn postgres_cycle() {
let ulid = Ulid::from_string("3Q38XWW0Q98GMAD3NHWZM2PZWZ").unwrap();

let mut w = bytes::BytesMut::new();
let t = &Type::UUID;
let _ = ulid.to_sql(t, &mut w);

assert_eq!(16, w.len());

let bs = w.bytes().map(|v| v.unwrap()).collect::<Vec<u8>>();

assert_eq!(ulid, Ulid::from_sql(t, &bs).unwrap());
}
}

0 comments on commit c09818d

Please sign in to comment.