pub mod bad_request;
pub mod general;
pub mod gone;
pub mod not_found;
pub mod proxy_request_refused;
pub use bad_request::BadRequest;
pub use general::General;
pub use gone::Gone;
pub use not_found::NotFound;
pub use proxy_request_refused::ProxyRequestRefused;
use anyhow::{bail, Result};
pub enum Permanent {
General(General),
NotFound(NotFound),
Gone(Gone),
ProxyRequestRefused(ProxyRequestRefused),
BadRequest(BadRequest),
}
impl Permanent {
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
if buffer.first().is_none_or(|b| *b != b'5') {
bail!("Unexpected first byte")
}
match buffer.get(1) {
Some(byte) => Ok(match byte {
b'0' => Self::General(General::from_bytes(buffer)?),
b'1' => Self::NotFound(NotFound::from_bytes(buffer)?),
b'2' => Self::Gone(Gone::from_bytes(buffer)?),
b'3' => Self::ProxyRequestRefused(ProxyRequestRefused::from_bytes(buffer)?),
b'9' => Self::BadRequest(BadRequest::from_bytes(buffer)?),
b => bail!("Unexpected second byte: {b}"),
}),
None => bail!("Invalid request"),
}
}
pub fn into_bytes(self) -> Vec<u8> {
match self {
Self::General(this) => this.into_bytes(),
Self::NotFound(this) => this.into_bytes(),
Self::Gone(this) => this.into_bytes(),
Self::ProxyRequestRefused(this) => this.into_bytes(),
Self::BadRequest(this) => this.into_bytes(),
}
}
}
#[test]
fn test() {
{
let source = format!("50 message\r\n");
let target = Permanent::from_bytes(source.as_bytes()).unwrap();
match target {
Permanent::General(ref this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("51 message\r\n");
let target = Permanent::from_bytes(source.as_bytes()).unwrap();
match target {
Permanent::NotFound(ref this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("52 message\r\n");
let target = Permanent::from_bytes(source.as_bytes()).unwrap();
match target {
Permanent::Gone(ref this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("53 message\r\n");
let target = Permanent::from_bytes(source.as_bytes()).unwrap();
match target {
Permanent::ProxyRequestRefused(ref this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("59 message\r\n");
let target = Permanent::from_bytes(source.as_bytes()).unwrap();
match target {
Permanent::BadRequest(ref this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
}