mirror of
https://github.com/YGGverse/titanite.git
synced 2026-03-31 09:05:31 +00:00
rename header to meta
This commit is contained in:
parent
7c62a393ed
commit
2d096515d4
6 changed files with 38 additions and 38 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue