use anyhow::{bail, Result};
pub const CODE: &[u8] = b"31";
pub struct Permanent {
pub target: String,
}
impl Permanent {
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
use crate::tool::Header;
let h = buffer.header_bytes()?;
if h.get(..2)
.is_none_or(|c| c[0] != CODE[0] || c[1] != CODE[1])
{
bail!("Invalid status code")
}
Ok(Self {
target: if h.is_empty() {
bail!("Target required")
} else {
String::from_utf8((h[3..]).to_vec())?
},
})
}
pub fn into_bytes(self) -> Vec<u8> {
let mut bytes = Vec::with_capacity(self.target.len() + 5);
bytes.extend(CODE);
bytes.push(b' ');
bytes.extend(self.target.into_bytes());
bytes.extend([b'\r', b'\n']);
bytes
}
}
#[test]
fn test() {
let request = format!("31 target\r\n");
let source = Permanent::from_bytes(request.as_bytes()).unwrap();
assert_eq!(source.target, "target".to_string());
assert_eq!(source.into_bytes(), request.as_bytes());
}