begin header holder implementation with lazy parser by getters, add request::Mode, add common header_bytes helper

This commit is contained in:
yggverse 2025-03-24 06:50:08 +02:00
parent a12a73d311
commit 7c518cecf6
13 changed files with 267 additions and 151 deletions

View file

@ -0,0 +1,27 @@
pub mod error;
pub mod header;
pub use error::Error;
pub use header::Header;
pub const CODE: &[u8] = b"20";
pub struct Default {
pub header: Header,
pub content: Option<Vec<u8>>,
}
impl Default {
// Constructors
pub fn parse(buffer: &[u8]) -> Result<Self, Error> {
if !buffer.starts_with(CODE) {
return Err(Error::Code);
}
let header = Header::parse(buffer).map_err(|e| Error::Header(e))?;
Ok(Self {
content: buffer.get(header.len() + 1..).map(|v| v.to_vec()),
header,
})
}
}

View file

@ -0,0 +1,20 @@
use std::fmt::{Display, Formatter, Result};
#[derive(Debug)]
pub enum Error {
Code,
Header(super::header::Error),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Code => {
write!(f, "Unexpected status code")
}
Self::Header(e) => {
write!(f, "Header error: {e}")
}
}
}
}

View file

@ -0,0 +1,43 @@
pub mod error;
pub use error::Error;
pub struct Header(Vec<u8>);
impl Header {
// Constructors
pub fn parse(buffer: &[u8]) -> Result<Self, Error> {
if !buffer.starts_with(super::CODE) {
return Err(Error::Code);
}
Ok(Self(
crate::client::connection::response::header_bytes(buffer)
.map_err(|e| Error::Header(e))?
.to_vec(),
))
}
// Getters
/// Parse content type for `Self`
pub fn mime(&self) -> Result<String, Error> {
glib::Regex::split_simple(
r"^\d{2}\s([^\/]+\/[^\s;]+)",
std::str::from_utf8(&self.0).map_err(|e| Error::Utf8Error(e))?,
glib::RegexCompileFlags::DEFAULT,
glib::RegexMatchFlags::DEFAULT,
)
.get(1)
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map_or(Err(Error::Mime), |s| Ok(s.to_lowercase()))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}

View file

@ -0,0 +1,31 @@
use std::{
fmt::{Display, Formatter, Result},
str::Utf8Error,
};
#[derive(Debug)]
pub enum Error {
Code,
Mime,
Header(crate::client::connection::response::HeaderBytesError),
Utf8Error(Utf8Error),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Code => {
write!(f, "Unexpected status code")
}
Self::Mime => {
write!(f, "Unexpected content type")
}
Self::Header(e) => {
write!(f, "Header error: {e}")
}
Self::Utf8Error(e) => {
write!(f, "UTF-8 error: {e}")
}
}
}
}

View file

@ -1,26 +1,19 @@
use std::{
fmt::{Display, Formatter, Result},
str::Utf8Error,
};
use std::fmt::{Display, Formatter, Result};
#[derive(Debug)]
pub enum Error {
Protocol,
Mime,
Utf8Error(Utf8Error),
Code,
Default(super::default::Error),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Utf8Error(e) => {
write!(f, "UTF-8 error: {e}")
Self::Code => {
write!(f, "Unexpected status code")
}
Self::Protocol => {
write!(f, "Protocol error")
}
Self::Mime => {
write!(f, "MIME error")
Self::Default(e) => {
write!(f, "Header error: {e}")
}
}
}