started response

This commit is contained in:
maxstrb 2025-10-11 18:52:40 +02:00
parent e209abe7a0
commit 9a2a500eb0
4 changed files with 278 additions and 25 deletions

View file

@ -1,22 +1,136 @@
use std::{io, str::FromStr};
pub enum ContentType {
#[derive(Debug)]
pub enum ContentTypeType {
Text(TextType),
Aplication(ApplicationType),
Image(Image),
Any,
}
#[derive(Debug)]
pub enum Parameter {
Preference(f32),
Charset(Charset),
Other(Box<str>, Box<str>),
}
#[derive(Debug)]
pub enum Charset {
UTF8,
}
#[derive(Debug)]
pub struct ContentType {
pub content_type: ContentTypeType,
pub parameter: Option<Parameter>,
}
pub fn InvalidDataError(error: &str) -> io::Error {
io::Error::new(io::ErrorKind::InvalidData, error)
}
impl FromStr for ContentType {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Err(io::Error::new(
io::ErrorKind::InvalidData,
"Invalid content-type",
))
match s.split(';').collect::<Vec<&str>>().as_slice() {
[val, par] => Ok(Self {
content_type: ContentTypeType::from_str(val)?,
parameter: Some(Parameter::from_str(par)?),
}),
[val] => Ok(Self {
content_type: ContentTypeType::from_str(val)?,
parameter: None,
}),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
"Invalid content-type",
)),
}
}
}
impl FromStr for Parameter {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.split('=').collect::<Vec<&str>>().as_slice() {
["q", value] => {
let pref_val = match value.parse::<f32>() {
Ok(v) => Ok(v),
Err(_) => Err(InvalidDataError("Invalid preference")),
}?;
Ok(Parameter::Preference(pref_val))
}
["charset", "utf-8"] => Ok(Parameter::Charset(Charset::UTF8)),
[t, v] => Ok(Parameter::Other(
t.to_string().into_boxed_str(),
v.to_string().into_boxed_str(),
)),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
"Invalid parameter",
)),
}
}
}
impl FromStr for ContentTypeType {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<&str> = s.split("/").collect();
match parts.as_slice() {
["*", "*"] => Ok(ContentTypeType::Any),
["text", "*"] => Ok(ContentTypeType::Text(TextType::Any)),
["text", "html"] => Ok(ContentTypeType::Text(TextType::Html)),
["text", "css"] => Ok(ContentTypeType::Text(TextType::Css)),
["text", "javascript"] => Ok(ContentTypeType::Text(TextType::Javascript)),
["application", "json"] => Ok(ContentTypeType::Aplication(ApplicationType::Json)),
["application", "xhtml+xml"] => {
Ok(ContentTypeType::Aplication(ApplicationType::XhtmlXml))
}
["application", "xml"] => Ok(ContentTypeType::Aplication(ApplicationType::Xml)),
["application", "*"] => Ok(ContentTypeType::Aplication(ApplicationType::Any)),
["image", "png"] => Ok(ContentTypeType::Image(Image::Png)),
["image", "jpeg"] | ["image", "jpg"] => Ok(ContentTypeType::Image(Image::Jpeg)),
["image", "avif"] => Ok(ContentTypeType::Image(Image::Avif)),
["image", "webp"] => Ok(ContentTypeType::Image(Image::Webp)),
["image", "svg"] | ["image", "svg+xml"] => Ok(ContentTypeType::Image(Image::Svg)),
["image", "*"] => Ok(ContentTypeType::Image(Image::Any)),
_ => {
println!("{parts:?}");
Err(io::Error::new(
io::ErrorKind::InvalidData,
"Invalid content-type-type",
))
}
}
}
}
#[derive(Debug)]
pub enum Image {
Png,
Avif,
Jpeg,
Webp,
Svg,
Any,
}
#[derive(Debug)]
pub enum TextType {
Html,
Css,
@ -24,7 +138,10 @@ pub enum TextType {
Any,
}
#[derive(Debug)]
pub enum ApplicationType {
Json,
Any,
XhtmlXml,
Xml,
}