1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
15#[serde(transparent)]
16#[repr(transparent)]
17pub struct DBson<T>(T);
18
19impl<T> From<T> for DBson<T> {
38 fn from(inner: T) -> Self {
39 Self(inner)
40 }
41}
42
43impl<T> DBson<T> {
44 pub fn new(inner: T) -> Self {
45 Self(inner)
46 }
47
48 pub fn into_inner(self) -> T {
49 self.0
50 }
51}
52
53#[cfg(feature = "rusqlite")]
54#[cfg_attr(docsrs, doc(cfg(feature = "rusqlite")))]
55mod impl_rusqlite {
56 use rusqlite::{types::FromSql, ToSql};
57 impl<T: serde::Serialize> ToSql for super::DBson<T> {
58 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
59 let bytes = bson::to_vec(&self.0)
60 .map_err(|e| rusqlite::Error::ToSqlConversionFailure(e.into()))?;
61 Ok(rusqlite::types::ToSqlOutput::Owned(
62 rusqlite::types::Value::Blob(bytes),
63 ))
64 }
65 }
66
67 impl<T: for<'de> serde::de::Deserialize<'de>> FromSql for super::DBson<T> {
68 fn column_result(
69 value: rusqlite::types::ValueRef<'_>,
70 ) -> rusqlite::types::FromSqlResult<Self> {
71 let bytes = value.as_blob()?;
72 let inner = bson::from_slice(bytes)
73 .map_err(|e| rusqlite::types::FromSqlError::Other(Box::new(e)))?;
74 Ok(Self::new(inner))
75 }
76 }
77}
78
79#[cfg(feature = "sqlx")]
80#[cfg_attr(docsrs, doc(cfg(feature = "sqlx")))]
81mod impl_sqlx {
82 use sqlx::{
83 database::{HasArguments, HasValueRef},
84 decode::Decode,
85 encode::Encode,
86 types::Type,
87 };
88
89 impl<'a, T: Serialize + serde::de::DeserializeOwned, DB: sqlx::database::Database> Type<DB>
90 for DBson<T>
91 where
92 &'a [u8]: Type<DB>,
93 {
94 fn type_info() -> DB::TypeInfo {
95 <&[u8] as ::sqlx::types::Type<DB>>::type_info()
96 }
97 }
98
99 impl<'a, T: Serialize + serde::de::DeserializeOwned, DB: sqlx::database::Database>
100 Encode<'a, DB> for DBson<T>
101 where
102 Vec<u8>: Type<DB>,
103 Vec<u8>: Encode<'a, DB>,
104 {
105 fn encode_by_ref(
106 &self,
107 buf: &mut <DB as HasArguments<'a>>::ArgumentBuffer,
108 ) -> sqlx::encode::IsNull {
109 let Ok(bytes) = bson::to_vec(&self.inner) else {
110 return sqlx::encode::IsNull::Yes;
111 };
112 <Vec<u8> as Encode<'a, DB>>::encode_by_ref(&bytes, buf)
113 }
114 fn encode(
115 self,
116 buf: &mut <DB as HasArguments<'a>>::ArgumentBuffer,
117 ) -> sqlx::encode::IsNull {
118 let Ok(bytes) = bson::to_vec(&self.inner) else {
119 return sqlx::encode::IsNull::Yes;
120 };
121 <Vec<u8> as Encode<'a, DB>>::encode(bytes, buf)
122 }
123 }
124
125 impl<'r, T: Serialize + serde::de::DeserializeOwned, DB: sqlx::database::Database>
126 Decode<'r, DB> for DBson<T>
127 where
128 &'r [u8]: Type<DB>,
129 &'r [u8]: Decode<'r, DB>,
130 {
131 fn decode(
132 value: <DB as HasValueRef<'r>>::ValueRef,
133 ) -> Result<Self, Box<dyn std::error::Error + Send + Sync + 'static>> {
134 let bytes = <&[u8] as Decode<'r, DB>>::decode(value)?;
135 let inner = bson::from_slice(&bytes)?;
136 Ok(Self { inner })
137 }
138 }
139}