Skip to content

Instantly share code, notes, and snippets.

@owenthewizard
Created October 28, 2025 00:54
Show Gist options
  • Save owenthewizard/278b744835746e99eba67585623e0ca3 to your computer and use it in GitHub Desktop.
Save owenthewizard/278b744835746e99eba67585623e0ca3 to your computer and use it in GitHub Desktop.
jiff-diesel
use diesel::deserialize::{self, FromSql};
use diesel::serialize::{self, IsNull, Output, ToSql};
use diesel::sql_types;
use diesel::sqlite::{Sqlite, SqliteValue};
use diesel_derives::{AsExpression, FromSqlRow};
#[derive(AsExpression, FromSqlRow, Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
#[diesel(sql_type = sql_types::Text)]
pub struct Date(jiff::civil::Date);
impl Date {
/// Converts this wrapper to a [`jiff::civil::Date`].
#[must_use]
pub const fn to_jiff(self) -> jiff::civil::Date {
self.0
}
}
impl From<jiff::civil::Date> for Date {
fn from(value: jiff::civil::Date) -> Self {
Self(value)
}
}
impl From<Date> for jiff::civil::Date {
fn from(value: Date) -> Self {
value.0
}
}
impl FromSql<sql_types::Text, Sqlite> for Date {
fn from_sql(mut value: SqliteValue<'_, '_, '_>) -> deserialize::Result<Self> {
Ok(Self(value.read_text().parse()?))
}
}
impl ToSql<sql_types::Text, Sqlite> for Date {
fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
out.set_value(self.0.to_string());
Ok(IsNull::No)
}
}
#[cfg(test)]
mod tests {
use super::*;
use diesel::connection::SimpleConnection;
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
use diesel_derives::Insertable;
diesel::table! {
jiff_date_roundtrip (id) {
id -> diesel::sql_types::Integer,
value -> Text,
}
}
#[derive(Insertable)]
#[diesel(table_name = jiff_date_roundtrip)]
struct NewDate {
value: Date,
}
#[test]
fn date_roundtrip_sqlite() {
let mut conn = SqliteConnection::establish(":memory:").unwrap();
conn.batch_execute(
"CREATE TABLE jiff_date_roundtrip (id INTEGER PRIMARY KEY AUTOINCREMENT, value TEXT NOT NULL)",
)
.unwrap();
let jiff_date = "2024-06-19".parse::<jiff::civil::Date>().unwrap();
let wrapped = Date::from(jiff_date);
diesel::insert_into(jiff_date_roundtrip::table)
.values(NewDate { value: wrapped })
.execute(&mut conn)
.unwrap();
let stored: Date = jiff_date_roundtrip::table
.select(jiff_date_roundtrip::value)
.first(&mut conn)
.unwrap();
assert_eq!(wrapped, stored);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment