cratestack_rusqlite/value/
bind.rs1use cratestack_core::Value;
7use cratestack_sql::SqlValue;
8use rusqlite::ToSql;
9use rusqlite::types::{ToSqlOutput, ValueRef};
10
11pub struct SqlValueParam<'a>(pub &'a SqlValue);
13
14impl<'a> ToSql for SqlValueParam<'a> {
15 fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
16 use rusqlite::types::Value as RV;
17
18 let value: ToSqlOutput<'_> = match self.0 {
19 SqlValue::Bool(v) => ToSqlOutput::Owned(RV::Integer(i64::from(*v))),
20 SqlValue::Int(v) => ToSqlOutput::Owned(RV::Integer(*v)),
21 SqlValue::Float(v) => ToSqlOutput::Owned(RV::Real(*v)),
22 SqlValue::String(v) => ToSqlOutput::Borrowed(ValueRef::Text(v.as_bytes())),
23 SqlValue::Bytes(v) => ToSqlOutput::Borrowed(ValueRef::Blob(v.as_slice())),
24 SqlValue::Uuid(v) => ToSqlOutput::Owned(RV::Text(v.hyphenated().to_string())),
25 SqlValue::DateTime(v) => ToSqlOutput::Owned(RV::Text(format_datetime(v))),
26 SqlValue::Json(v) => ToSqlOutput::Owned(RV::Text(format_json(v))),
27 SqlValue::Decimal(v) => ToSqlOutput::Owned(RV::Text(format_decimal(v))),
28 SqlValue::NullBool
29 | SqlValue::NullInt
30 | SqlValue::NullFloat
31 | SqlValue::NullString
32 | SqlValue::NullBytes
33 | SqlValue::NullUuid
34 | SqlValue::NullDateTime
35 | SqlValue::NullJson
36 | SqlValue::NullDecimal => ToSqlOutput::Owned(RV::Null),
37 SqlValue::Vector(_) | SqlValue::NullVector => {
46 return Err(rusqlite::Error::ToSqlConversionFailure(
47 "Vector(n) fields are not supported by the embedded (rusqlite) backend".into(),
48 ));
49 }
50 };
51 Ok(value)
52 }
53}
54
55fn format_datetime(value: &chrono::DateTime<chrono::Utc>) -> String {
56 value.to_rfc3339_opts(chrono::SecondsFormat::Micros, true)
57}
58
59fn format_json(value: &Value) -> String {
63 serde_json::to_string(&value.to_plain_json()).unwrap_or_else(|_| "null".to_string())
64}
65
66fn format_decimal(value: &cratestack_core::Decimal) -> String {
67 value.to_string()
68}