From bf4ac4bd27149a58a112ebbbf7f9b6b1da7247f9 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 16 Mar 2025 14:43:08 +0200 Subject: [PATCH] rename constructor, implement zero-copy trait, remove extra regex parser --- src/line/quote.rs | 56 ++++++++++++++++++++++++++++++++++---------- tests/integration.rs | 2 +- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/src/line/quote.rs b/src/line/quote.rs index 8926165..5ac1fb2 100644 --- a/src/line/quote.rs +++ b/src/line/quote.rs @@ -1,4 +1,5 @@ -use glib::{Regex, RegexCompileFlags, RegexMatchFlags}; +/// [Quote item](https://geminiprotocol.net/docs/gemtext-specification.gmi#quote-lines) tag +pub const TAG: char = '>'; /// [Quote](https://geminiprotocol.net/docs/gemtext-specification.gmi#quote-lines) entity holder pub struct Quote { @@ -8,19 +9,48 @@ pub struct Quote { impl Quote { // Constructors - /// Parse `Self` from line string - pub fn from(line: &str) -> Option { - // Parse line - let regex = Regex::split_simple( - r"^>\s*(.*)$", - line, - RegexCompileFlags::DEFAULT, - RegexMatchFlags::DEFAULT, - ); - - // Extract formatted value + /// Parse `Self` from [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line + pub fn parse(line: &str) -> Option { Some(Self { - value: regex.get(1)?.trim().to_string(), + value: line.as_value()?.to_string(), }) } + + // Converters + + /// Convert `Self` to [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line + pub fn to_source(&self) -> String { + self.value.to_source() + } +} + +pub trait Gemtext { + /// Get [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) value from `Self` + fn as_value(&self) -> Option<&Self>; + /// Convert `Self` to [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line + fn to_source(&self) -> String; +} + +impl Gemtext for str { + fn as_value(&self) -> Option<&Self> { + self.strip_prefix(TAG).map(|s| s.trim()) + } + fn to_source(&self) -> String { + format!("{TAG} {}", self.trim()) + } +} + +#[test] +fn test() { + const SOURCE: &str = "> Quote"; + const VALUE: &str = "Quote"; + + // test `Quote` + let quote = Quote::parse(SOURCE).unwrap(); + assert_eq!(quote.value, VALUE); + assert_eq!(quote.to_source(), SOURCE); + + // test `Gemtext` + assert_eq!(SOURCE.as_value(), Some(VALUE)); + assert_eq!(VALUE.to_source(), SOURCE) } diff --git a/tests/integration.rs b/tests/integration.rs index 2b4731b..90c85dc 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -78,7 +78,7 @@ fn gemtext() { } // Quote - if let Some(result) = Quote::from(line) { + if let Some(result) = Quote::parse(line) { quote.push(result); continue; }