1#![forbid(unsafe_code)]
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5use core::ops::{Deref, DerefMut};
6
7use prost::Message;
8use sqlx::decode::Decode;
9use sqlx::encode::{Encode, IsNull};
10use sqlx::error::BoxDynError;
11use sqlx::{Database, Type};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
15pub struct SqlxProto<T>(pub T)
16where
17 T: Message;
18
19impl<T> Default for SqlxProto<T>
20where
21 T: Message + Default,
22{
23 #[inline]
24 fn default() -> Self {
25 Self(T::default())
26 }
27}
28
29impl<T> SqlxProto<T>
30where
31 T: Message,
32{
33 #[inline]
35 pub fn into_inner(self) -> T {
36 self.0
37 }
38}
39
40impl<T> From<T> for SqlxProto<T>
41where
42 T: Message,
43{
44 #[inline]
45 fn from(value: T) -> SqlxProto<T> {
46 Self(value)
47 }
48}
49
50impl<T> AsRef<T> for SqlxProto<T>
51where
52 T: Message,
53{
54 #[inline]
55 fn as_ref(&self) -> &T {
56 &self.0
57 }
58}
59
60impl<T> AsMut<T> for SqlxProto<T>
61where
62 T: Message,
63{
64 #[inline]
65 fn as_mut(&mut self) -> &mut T {
66 &mut self.0
67 }
68}
69
70impl<T> Deref for SqlxProto<T>
71where
72 T: Message,
73{
74 type Target = T;
75
76 #[inline]
77 fn deref(&self) -> &Self::Target {
78 &self.0
79 }
80}
81
82impl<T> DerefMut for SqlxProto<T>
83where
84 T: Message,
85{
86 #[inline]
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.0
89 }
90}
91
92impl<T, DB> Type<DB> for SqlxProto<T>
93where
94 T: Message,
95 DB: Database,
96 Vec<u8>: Type<DB>,
97{
98 fn type_info() -> DB::TypeInfo {
99 <Vec<u8> as Type<DB>>::type_info()
100 }
101}
102
103impl<'a, T, DB> Encode<'a, DB> for SqlxProto<T>
104where
105 T: Message,
106 DB: Database,
107 Vec<u8>: Encode<'a, DB>,
108{
109 fn encode_by_ref(
110 &self,
111 buf: &mut <DB as Database>::ArgumentBuffer<'a>,
112 ) -> Result<IsNull, BoxDynError> {
113 let bytes = self.0.encode_to_vec();
114 <Vec<u8> as Encode<DB>>::encode_by_ref(&bytes, buf)
115 }
116}
117
118impl<'r, T, DB> Decode<'r, DB> for SqlxProto<T>
119where
120 T: Message + Default,
121 DB: Database,
122 Vec<u8>: Decode<'r, DB>,
123{
124 fn decode(value: <DB as Database>::ValueRef<'r>) -> Result<Self, BoxDynError> {
125 let bytes: Vec<u8> = <Vec<u8> as Decode<DB>>::decode(value)?;
126 Ok(Self(T::decode(bytes.as_slice())?))
127 }
128}