pub mod cgi_error;
pub mod general;
pub mod proxy_error;
pub mod server_unavailable;
pub mod slow_down;
pub use cgi_error::CgiError;
pub use general::General;
pub use proxy_error::ProxyError;
pub use server_unavailable::ServerUnavailable;
pub use slow_down::SlowDown;
use anyhow::{bail, Result};
pub enum Temporary {
General(General),
ServerUnavailable(ServerUnavailable),
CgiError(CgiError),
ProxyError(ProxyError),
SlowDown(SlowDown),
}
impl Temporary {
pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
if buffer.first().is_none_or(|b| *b != b'4') {
bail!("Unexpected first byte")
}
match buffer.get(1) {
Some(byte) => Ok(match byte {
b'0' => Self::General(General::from_bytes(buffer)?),
b'1' => Self::ServerUnavailable(ServerUnavailable::from_bytes(buffer)?),
b'2' => Self::CgiError(CgiError::from_bytes(buffer)?),
b'3' => Self::ProxyError(ProxyError::from_bytes(buffer)?),
b'4' => Self::SlowDown(SlowDown::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::ServerUnavailable(this) => this.into_bytes(),
Self::CgiError(this) => this.into_bytes(),
Self::ProxyError(this) => this.into_bytes(),
Self::SlowDown(this) => this.into_bytes(),
}
}
}
#[test]
fn test() {
{
let source = format!("40 message\r\n");
let target = Temporary::from_bytes(source.as_bytes()).unwrap();
match target {
Temporary::General(ref this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("41 message\r\n");
let target = Temporary::from_bytes(source.as_bytes()).unwrap();
match target {
Temporary::ServerUnavailable(ref this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("42 message\r\n");
let target = Temporary::from_bytes(source.as_bytes()).unwrap();
match target {
Temporary::CgiError(ref this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("43 message\r\n");
let target = Temporary::from_bytes(source.as_bytes()).unwrap();
match target {
Temporary::ProxyError(ref this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("44 message\r\n");
let target = Temporary::from_bytes(source.as_bytes()).unwrap();
match target {
Temporary::SlowDown(ref this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
}