use bincode::de::Decoder; use bincode::enc::write::Writer; use bincode::enc::Encoder; use bincode::error::{DecodeError, EncodeError}; use bincode::{BorrowDecode, Decode, Encode}; /// PostgreSQL format of string encoded as a null-terminated string. #[derive(Debug, Clone, BorrowDecode)] pub struct PgString(String); impl PgString { pub fn as_str(&self) -> &str { &self.0 } } impl From<&str> for PgString { fn from(string: &str) -> Self { PgString(string.to_string()) } } impl From for String { fn from(pg_string: PgString) -> Self { pg_string.0 } } impl From for PgString { fn from(string: String) -> Self { PgString(string) } } impl Encode for PgString { fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { encoder.writer().write(self.0.as_bytes())?; encoder.writer().write(b"\0") } } impl Decode for PgString { fn decode(decoder: &mut D) -> Result { let mut bytes = Vec::new(); loop { let byte = u8::decode(decoder)?; if byte == 0 { break; } bytes.push(byte); } let string = String::from_utf8(bytes).map_err(|e| DecodeError::Utf8 { inner: e.utf8_error(), })?; Ok(PgString(string)) } } #[cfg(test)] mod tests { use super::*; use crate::message::primitive::data::MessageData; #[test] fn test_encode_decode_utf8() { let pg_string = PgString::from("áhój jěžkó"); let encoded = pg_string.serialize().unwrap(); let decoded: PgString = PgString::deserialize(&encoded).unwrap(); let actual = decoded.as_str(); assert_eq!("áhój jěžkó", actual); } }