pub mod certificate;
pub mod failure;
pub mod input;
pub mod redirect;
pub mod success;
pub use certificate::Certificate;
pub use failure::Failure;
pub use input::Input;
pub use redirect::Redirect;
pub use success::Success;
use anyhow::{bail, Result};
pub enum Response<'a> {
Certificate(Certificate),
Failure(Failure),
Input(Input),
Redirect(Redirect),
Success(Success<'a>),
}
impl<'a> Response<'a> {
pub fn from_bytes(buffer: &'a [u8]) -> Result<Self> {
match buffer.first() {
Some(byte) => Ok(match byte {
b'1' => Self::Input(Input::from_bytes(buffer)?),
b'2' => Self::Success(Success::from_bytes(buffer)?),
b'3' => Self::Redirect(Redirect::from_bytes(buffer)?),
b'4' | b'5' => Self::Failure(Failure::from_bytes(buffer)?),
b'6' => Self::Certificate(Certificate::from_bytes(buffer)?),
b => bail!("Unspecified header byte: {b}"),
}),
None => bail!("Empty source"),
}
}
pub fn into_bytes(self) -> Vec<u8> {
match self {
Self::Certificate(this) => this.into_bytes(),
Self::Failure(this) => this.into_bytes(),
Self::Input(this) => this.into_bytes(),
Self::Redirect(this) => this.into_bytes(),
Self::Success(this) => this.into_bytes(),
}
}
}
#[test]
fn test() {
{
let source = format!("10 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Input(ref this) => match this {
Input::Default(this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("11 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Input(ref this) => match this {
Input::Sensitive(this) => assert_eq!(this.message, Some("message".to_string())),
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("20 text/gemini\r\ndata");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Success(ref this) => match this {
Success::Default(this) => {
assert_eq!(this.meta.mime, "text/gemini");
assert_eq!(this.data, "data".as_bytes());
}
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("30 target\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Redirect(ref this) => match this {
Redirect::Temporary(this) => assert_eq!(this.target, "target"),
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("31 target\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Redirect(ref this) => match this {
Redirect::Permanent(this) => assert_eq!(this.target, "target"),
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
use failure::Temporary;
{
let source = format!("40 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Temporary(this) => match this {
Temporary::General(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("41 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Temporary(this) => match this {
Temporary::ServerUnavailable(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("42 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Temporary(this) => match this {
Temporary::CgiError(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("43 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Temporary(this) => match this {
Temporary::ProxyError(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("44 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Temporary(this) => match this {
Temporary::SlowDown(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
}
{
use failure::Permanent;
{
let source = format!("50 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Permanent(this) => match this {
Permanent::General(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("51 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Permanent(this) => match this {
Permanent::NotFound(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("52 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Permanent(this) => match this {
Permanent::Gone(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("53 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Permanent(this) => match this {
Permanent::ProxyRequestRefused(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("59 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Failure(ref this) => match this {
Failure::Permanent(this) => match this {
Permanent::BadRequest(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
}
{
let source = format!("60 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Certificate(ref this) => match this {
Certificate::Expected(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("61 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Certificate(ref this) => match this {
Certificate::NotAuthorized(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
{
let source = format!("62 message\r\n");
let target = Response::from_bytes(source.as_bytes()).unwrap();
match target {
Response::Certificate(ref this) => match this {
Certificate::NotValid(this) => {
assert_eq!(this.message, Some("message".to_string()))
}
_ => panic!(),
},
_ => panic!(),
}
assert_eq!(target.into_bytes(), source.as_bytes());
}
}