From 21ac9005768a82378cb09dbd82f28f38d0c363b8 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 22 Feb 2025 06:06:31 +0200 Subject: [PATCH] add Header trait with shared bytes impl --- src/lib.rs | 26 ++++++++++++++++++++++++++ src/request.rs | 19 +------------------ src/request/gemini.rs | 3 ++- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 601e534..a31205d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,29 @@ pub mod response; pub use request::Request; pub use response::Response; + +pub const HEADER_MAX_LEN: usize = 1024; + +pub trait Header { + fn header_bytes(&self) -> Result<&[u8]>; +} + +impl Header for &[u8] { + fn header_bytes(&self) -> Result<&[u8]> { + match self.iter().position(|&b| b == b'\r') { + Some(n) => { + if n > HEADER_MAX_LEN { + bail!("Header bytes length reached") + } + if self.get(n + 1).is_some_and(|&b| b == b'\n') { + Ok(&self[..n]) + } else { + bail!("LF byte not found") + } + } + None => bail!("CR byte not found"), + } + } +} + +use anyhow::{bail, Result}; diff --git a/src/request.rs b/src/request.rs index 4cf75de..bea9345 100644 --- a/src/request.rs +++ b/src/request.rs @@ -4,8 +4,7 @@ pub mod titan; pub use gemini::Gemini; pub use titan::Titan; -pub const HEADER_MAX_LEN: usize = 1024; - +use super::Header; use anyhow::{bail, Result}; /// https://geminiprotocol.net/docs/protocol-specification.gmi#requests @@ -32,19 +31,3 @@ impl<'a> Request<'a> { } } } - -pub fn header_bytes(buffer: &[u8]) -> Result<&[u8]> { - match buffer.iter().position(|&b| b == b'\r') { - Some(n) => { - if n > HEADER_MAX_LEN { - bail!("Header bytes length reached") - } - if buffer.get(n + 1).is_some_and(|&b| b == b'\n') { - Ok(&buffer[..n]) - } else { - bail!("LF byte not found") - } - } - None => bail!("CR byte not found"), - } -} diff --git a/src/request/gemini.rs b/src/request/gemini.rs index c57f38a..fc2dc08 100644 --- a/src/request/gemini.rs +++ b/src/request/gemini.rs @@ -8,8 +8,9 @@ pub struct Gemini { impl Gemini { pub fn from_bytes(buffer: &[u8]) -> Result { + use super::Header; Ok(Self { - url: Url::parse(std::str::from_utf8(crate::request::header_bytes(buffer)?)?)?, + url: Url::parse(std::str::from_utf8(buffer.header_bytes()?)?)?, }) } pub fn into_bytes(self) -> Vec {