1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
#[derive(Clone, Debug, PartialEq)] pub struct Bytea(Vec<u8>); impl From<Vec<u8>> for Bytea { fn from(vec: Vec<u8>) -> Self { Self(vec) } } impl std::ops::Deref for Bytea { type Target = Vec<u8>; fn deref(&self) -> &Self::Target { &self.0 } } impl crate::ToSql for Bytea { fn ty(&self) -> crate::pq::Type { crate::pq::types::BYTEA } fn format(&self) -> crate::pq::Format { crate::pq::Format::Binary } fn to_sql(&self) -> crate::Result<Option<Vec<u8>>> { Ok(Some(self.to_vec())) } } impl crate::FromSql for Bytea { fn from_text( _: &crate::pq::Type, raw: Option<&str>, ) -> crate::Result<Self> { let x: &[_] = &['\\', 'x']; let string = crate::not_null(raw)?.trim_start_matches(x); let mut pos = 0; let mut v = Vec::new(); while pos < string.len() { v.push(u8::from_str_radix(&string[pos..pos + 2], 16).unwrap()); pos += 2; } Ok(v.into()) } fn from_binary( _: &crate::pq::Type, raw: Option<&[u8]>, ) -> crate::Result<Self> { Ok(crate::not_null(raw)?.to_vec().into()) } } #[cfg(test)] mod test { crate::sql_test!(bytea, crate::Bytea, [( "'abcd'", crate::Bytea::from(Vec::from("abcd")) )]); }