From dbe53e5d87079a5ce3c4f1c558bd5fe6479abcd9 Mon Sep 17 00:00:00 2001 From: gwenn Date: Sat, 27 Jul 2024 10:24:52 +0200 Subject: [PATCH] Oops --- src/types/jiff.rs | 137 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/types/jiff.rs diff --git a/src/types/jiff.rs b/src/types/jiff.rs new file mode 100644 index 0000000..5b97e87 --- /dev/null +++ b/src/types/jiff.rs @@ -0,0 +1,137 @@ +//! Convert some `jiff` types. + +use jiff::civil::{Date, DateTime, Time}; +use std::str::FromStr; + +use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef}; +use crate::Result; + +/// Gregorian calendar date => "YYYY-MM-DD" +impl ToSql for Date { + #[inline] + fn to_sql(&self) -> Result> { + let s = self.to_string(); + Ok(ToSqlOutput::from(s)) + } +} + +/// "YYYY-MM-DD" => Gregorian calendar date. +impl FromSql for Date { + #[inline] + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + value.as_str().and_then(|s| match Date::from_str(s) { + Ok(d) => Ok(d), + Err(err) => Err(FromSqlError::Other(Box::new(err))), + }) + } +} +/// time => "HH:MM:SS.SSS" +impl ToSql for Time { + #[inline] + fn to_sql(&self) -> Result> { + let date_str = self.to_string(); + Ok(ToSqlOutput::from(date_str)) + } +} + +/// "HH:MM:SS.SSS" => time. +impl FromSql for Time { + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + value.as_str().and_then(|s| match Time::from_str(s) { + Ok(t) => Ok(t), + Err(err) => Err(FromSqlError::Other(Box::new(err))), + }) + } +} + +/// Gregorian datetime => "YYYY-MM-DDTHH:MM:SS.SSS" +impl ToSql for DateTime { + #[inline] + fn to_sql(&self) -> Result> { + let s = self.to_string(); + Ok(ToSqlOutput::from(s)) + } +} + +/// "YYYY-MM-DDTHH:MM:SS.SSS" => Gregorian datetime. +impl FromSql for DateTime { + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + value.as_str().and_then(|s| match DateTime::from_str(s) { + Ok(dt) => Ok(dt), + Err(err) => Err(FromSqlError::Other(Box::new(err))), + }) + } +} + +#[cfg(test)] +mod test { + use crate::{Connection, Result}; + use jiff::civil::{Date, DateTime, Time}; + + fn checked_memory_handle() -> Result { + let db = Connection::open_in_memory()?; + db.execute_batch("CREATE TABLE foo (t TEXT, b BLOB)")?; + Ok(db) + } + + #[test] + fn test_date() -> Result<()> { + let db = checked_memory_handle()?; + let date = Date::constant(2016, 2, 23); + db.execute("INSERT INTO foo (t) VALUES (?1)", [date])?; + + let s: String = db.one_column("SELECT t FROM foo")?; + assert_eq!("2016-02-23", s); + let t: Date = db.one_column("SELECT t FROM foo")?; + assert_eq!(date, t); + + db.execute("UPDATE foo set b = date(t)", [])?; + let t: Date = db.one_column("SELECT b FROM foo")?; + assert_eq!(date, t); + + let r: Result = db.one_column("SELECT '2023-02-29'"); + assert!(r.is_err()); + Ok(()) + } + + #[test] + fn test_time() -> Result<()> { + let db = checked_memory_handle()?; + let time = Time::constant(23, 56, 4, 0); + db.execute("INSERT INTO foo (t) VALUES (?1)", [time])?; + + let s: String = db.one_column("SELECT t FROM foo")?; + assert_eq!("23:56:04", s); + let v: Time = db.one_column("SELECT t FROM foo")?; + assert_eq!(time, v); + + db.execute("UPDATE foo set b = time(t)", [])?; + let v: Time = db.one_column("SELECT b FROM foo")?; + assert_eq!(time, v); + + let r: Result