rename header to meta

This commit is contained in:
yggverse 2025-02-23 10:19:39 +02:00
parent 7c62a393ed
commit 2d096515d4
6 changed files with 38 additions and 38 deletions

View file

@ -1,23 +1,23 @@
pub mod header; pub mod meta;
pub use header::Header; pub use meta::Meta;
/// [Titan](gemini://transjovian.org/titan/page/The%20Titan%20Specification) request /// [Titan](gemini://transjovian.org/titan/page/The%20Titan%20Specification) request
pub struct Titan<'a> { pub struct Titan<'a> {
pub data: &'a [u8], pub data: &'a [u8],
pub header: Header, pub meta: Meta,
} }
impl<'a> Titan<'a> { impl<'a> Titan<'a> {
pub fn from_bytes(buffer: &'a [u8]) -> Result<Self> { pub fn from_bytes(buffer: &'a [u8]) -> Result<Self> {
let header = Header::from_bytes(buffer)?; let meta = Meta::from_bytes(buffer)?;
let data = buffer.get(header.to_bytes().len()..).unwrap_or(&[]); let data = buffer.get(meta.to_bytes().len()..).unwrap_or(&[]);
if header.size != data.len() { if meta.size != data.len() {
bail!("Data size mismatch ({}:{})", header.size, data.len()) bail!("Data size mismatch ({}:{})", meta.size, data.len())
} }
Ok(Self { data, header }) Ok(Self { data, meta })
} }
pub fn into_bytes(self) -> Vec<u8> { pub fn into_bytes(self) -> Vec<u8> {
let mut bytes = self.header.into_bytes(); let mut bytes = self.meta.into_bytes();
bytes.extend(self.data); bytes.extend(self.data);
bytes bytes
} }

View file

@ -1,4 +1,4 @@
pub struct Header { pub struct Meta {
pub size: usize, pub size: usize,
pub url: Url, pub url: Url,
pub mime: Option<String>, pub mime: Option<String>,
@ -6,7 +6,7 @@ pub struct Header {
pub options: Option<IndexMap<String, String>>, pub options: Option<IndexMap<String, String>>,
} }
impl Header { impl Meta {
pub fn from_bytes(buffer: &[u8]) -> Result<Self> { pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
use crate::Header; use crate::Header;
use regex::Regex; use regex::Regex;
@ -67,24 +67,24 @@ impl Header {
self.to_bytes() self.to_bytes()
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
let mut header = format!("{};size={}", self.url, self.size); let mut meta = format!("{};size={}", self.url, self.size);
if let Some(ref mime) = self.mime { if let Some(ref mime) = self.mime {
header.push_str(&format!(";mime={mime}")); meta.push_str(&format!(";mime={mime}"));
} }
if let Some(ref token) = self.token { if let Some(ref token) = self.token {
header.push_str(&format!(";token={token}")); meta.push_str(&format!(";token={token}"));
} }
if let Some(ref options) = self.options { if let Some(ref options) = self.options {
header.push('?'); meta.push('?');
let mut items = Vec::new(); let mut items = Vec::new();
for (k, v) in options { for (k, v) in options {
items.push(format!("{k}={v}")); items.push(format!("{k}={v}"));
} }
header.push_str(&items.join("&")); meta.push_str(&items.join("&"));
} }
header.push('\r'); meta.push('\r');
header.push('\n'); meta.push('\n');
header.into_bytes() meta.into_bytes()
} }
} }
@ -94,12 +94,12 @@ fn test() {
"titan://geminiprotocol.net/raw/path;size=4;mime=text/plain;token=token?key1=value1&key2=value2\r\nDATA" "titan://geminiprotocol.net/raw/path;size=4;mime=text/plain;token=token?key1=value1&key2=value2\r\nDATA"
.as_bytes(); .as_bytes();
let bytes = Header::from_bytes(BYTES).unwrap().into_bytes(); let meta = Meta::from_bytes(BYTES).unwrap().into_bytes();
// println!("{:?}", from_utf8(&bytes)); // println!("{:?}", from_utf8(&bytes));
// println!("{:?}", from_utf8(&BYTES)); // println!("{:?}", from_utf8(&BYTES));
assert_eq!(bytes, BYTES[..BYTES.len() - 4]); // skip DATA assert_eq!(meta, BYTES[..BYTES.len() - 4]); // skip DATA
} }
use anyhow::{bail, Result}; use anyhow::{bail, Result};

View file

@ -84,7 +84,7 @@ fn test() {
match target { match target {
Response::Success(ref this) => match this { Response::Success(ref this) => match this {
Success::Default(this) => { Success::Default(this) => {
assert_eq!(this.header.mime, "text/gemini"); assert_eq!(this.meta.mime, "text/gemini");
assert_eq!(this.data, "data".as_bytes()); assert_eq!(this.data, "data".as_bytes());
} }
}, },

View file

@ -35,7 +35,7 @@ fn test() {
match source { match source {
Success::Default(ref this) => { Success::Default(ref this) => {
assert_eq!(this.header.mime, "text/gemini"); assert_eq!(this.meta.mime, "text/gemini");
assert_eq!(this.data, "DATA".as_bytes()); assert_eq!(this.data, "DATA".as_bytes());
} }
} }

View file

@ -1,27 +1,27 @@
pub mod header; pub mod meta;
pub use header::Header; pub use meta::Meta;
/// [Success](https://geminiprotocol.net/docs/protocol-specification.gmi#success) /// [Success](https://geminiprotocol.net/docs/protocol-specification.gmi#success)
pub struct Default<'a> { pub struct Default<'a> {
pub data: &'a [u8], pub data: &'a [u8],
pub header: Header, pub meta: Meta,
} }
impl<'a> Default<'a> { impl<'a> Default<'a> {
/// Build `Self` from UTF-8 header bytes /// Build `Self` from UTF-8 meta bytes
/// * expected buffer includes leading status code, message, CRLF /// * expected buffer includes leading status code, message, CRLF
pub fn from_bytes(buffer: &'a [u8]) -> Result<Self> { pub fn from_bytes(buffer: &'a [u8]) -> Result<Self> {
let header = Header::from_bytes(buffer)?; let meta = Meta::from_bytes(buffer)?;
Ok(Self { Ok(Self {
data: buffer.get(header.to_bytes().len()..).unwrap_or(&[]), data: buffer.get(meta.to_bytes().len()..).unwrap_or(&[]),
header, meta,
}) })
} }
/// Convert `Self` into UTF-8 bytes presentation /// Convert `Self` into UTF-8 bytes presentation
pub fn into_bytes(self) -> Vec<u8> { pub fn into_bytes(self) -> Vec<u8> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
bytes.extend(self.header.into_bytes()); bytes.extend(self.meta.into_bytes());
bytes.extend(self.data); bytes.extend(self.data);
bytes bytes
} }
@ -32,7 +32,7 @@ fn test() {
const BYTES: &[u8] = "20 text/gemini\r\nDATA".as_bytes(); const BYTES: &[u8] = "20 text/gemini\r\nDATA".as_bytes();
let default = Default::from_bytes(BYTES).unwrap(); let default = Default::from_bytes(BYTES).unwrap();
assert_eq!(default.header.mime, "text/gemini".to_string()); assert_eq!(default.meta.mime, "text/gemini".to_string());
assert_eq!(default.into_bytes(), BYTES); assert_eq!(default.into_bytes(), BYTES);
} }

View file

@ -1,11 +1,11 @@
pub const CODE: &[u8] = b"20"; pub const CODE: &[u8] = b"20";
pub struct Header { pub struct Meta {
pub mime: String, pub mime: String,
} }
impl Header { impl Meta {
/// Build `Self` from UTF-8 header bytes /// Build `Self` from UTF-8 meta bytes
/// * expected buffer includes leading status code, message, CRLF /// * expected buffer includes leading status code, message, CRLF
pub fn from_bytes(buffer: &[u8]) -> Result<Self> { pub fn from_bytes(buffer: &[u8]) -> Result<Self> {
use crate::Header; use crate::Header;
@ -46,10 +46,10 @@ impl Header {
#[test] #[test]
fn test() { fn test() {
const BYTES: &[u8] = "20 text/gemini\r\nDATA".as_bytes(); const BYTES: &[u8] = "20 text/gemini\r\nDATA".as_bytes();
let header = Header::from_bytes(BYTES).unwrap(); let meta = Meta::from_bytes(BYTES).unwrap();
assert_eq!(header.mime, "text/gemini".to_string()); assert_eq!(meta.mime, "text/gemini".to_string());
assert_eq!(header.into_bytes(), BYTES[..BYTES.len() - 4]); // skip DATA assert_eq!(meta.into_bytes(), BYTES[..BYTES.len() - 4]); // skip DATA
} }
use anyhow::{bail, Result}; use anyhow::{bail, Result};