74 lines
1.8 KiB
Rust
74 lines
1.8 KiB
Rust
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<PgString> for String {
|
|
fn from(pg_string: PgString) -> Self {
|
|
pg_string.0
|
|
}
|
|
}
|
|
|
|
impl From<String> for PgString {
|
|
fn from(string: String) -> Self {
|
|
PgString(string)
|
|
}
|
|
}
|
|
|
|
impl Encode for PgString {
|
|
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
|
|
encoder.writer().write(self.0.as_bytes())?;
|
|
encoder.writer().write(b"\0")
|
|
}
|
|
}
|
|
|
|
impl Decode for PgString {
|
|
fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
|
|
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);
|
|
}
|
|
}
|