mirror of
https://github.com/YGGverse/ggemtext.git
synced 2026-03-31 17:15:33 +00:00
remove regex dependency, rename constructor, implement zero-copy trait
This commit is contained in:
parent
7f3ea670f1
commit
96f7d648b6
3 changed files with 71 additions and 20 deletions
|
|
@ -1,5 +1,7 @@
|
||||||
|
pub mod gemtext;
|
||||||
|
pub use gemtext::Gemtext;
|
||||||
|
|
||||||
use super::TAG;
|
use super::TAG;
|
||||||
use glib::{Regex, RegexCompileFlags, RegexMatchFlags};
|
|
||||||
|
|
||||||
/// Inline [preformatted](https://geminiprotocol.net/docs/gemtext-specification.gmi#in-pre-formatted-mode) entity holder
|
/// Inline [preformatted](https://geminiprotocol.net/docs/gemtext-specification.gmi#in-pre-formatted-mode) entity holder
|
||||||
pub struct Inline {
|
pub struct Inline {
|
||||||
|
|
@ -10,24 +12,35 @@ impl Inline {
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
/// Parse `Self` from line string
|
/// Parse `Self` from line string
|
||||||
pub fn from(line: &str) -> Option<Self> {
|
pub fn parse(line: &str) -> Option<Self> {
|
||||||
// Skip next operations on prefix and postfix mismatch `TAG`
|
line.as_value().map(|v| Self {
|
||||||
// * replace regex implementation @TODO
|
value: v.to_string(),
|
||||||
if !line.starts_with(TAG) && !line.ends_with(TAG) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse line
|
|
||||||
let regex = Regex::split_simple(
|
|
||||||
r"^`{3}([^`]+)`{3}$",
|
|
||||||
line,
|
|
||||||
RegexCompileFlags::DEFAULT,
|
|
||||||
RegexMatchFlags::DEFAULT,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Extract formatted value
|
|
||||||
Some(Self {
|
|
||||||
value: regex.get(1)?.trim().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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
fn assert(source: &str, value: &str) {
|
||||||
|
let list = Inline::parse(source).unwrap();
|
||||||
|
assert_eq!(list.value, value);
|
||||||
|
assert_eq!(list.to_source(), format!("```{value}```"));
|
||||||
|
}
|
||||||
|
assert("```inline```", "inline");
|
||||||
|
assert("```inline ```", "inline");
|
||||||
|
assert("``` inline ```", "inline");
|
||||||
|
assert("``` inline```", "inline");
|
||||||
|
assert("``` inline``` ", "inline");
|
||||||
|
assert("``````inline``` ", "```inline");
|
||||||
|
assert("``````inline`````` ", "```inline```");
|
||||||
|
assert("```inline`````` ", "inline```");
|
||||||
|
assert!("```inline".as_value().is_none());
|
||||||
|
assert!("```inline``` ne".as_value().is_none());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
38
src/line/code/inline/gemtext.rs
Normal file
38
src/line/code/inline/gemtext.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use super::TAG;
|
||||||
|
|
||||||
|
pub trait Gemtext {
|
||||||
|
/// Get [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) value for `Self`
|
||||||
|
fn as_value(&self) -> Option<&str>;
|
||||||
|
/// 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<&str> {
|
||||||
|
if let Some(p) = self.strip_prefix(TAG) {
|
||||||
|
return p.trim().strip_suffix(TAG).map(|s| s.trim());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn to_source(&self) -> String {
|
||||||
|
format!("{TAG}{}{TAG}", self.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
fn assert(source: &str, value: &str) {
|
||||||
|
assert_eq!(source.as_value(), Some(value));
|
||||||
|
assert_eq!(value.to_source(), format!("```{value}```"));
|
||||||
|
}
|
||||||
|
assert("```inline```", "inline");
|
||||||
|
assert("```inline ```", "inline");
|
||||||
|
assert("``` inline ```", "inline");
|
||||||
|
assert("``` inline```", "inline");
|
||||||
|
assert("``` inline``` ", "inline");
|
||||||
|
assert("``````inline``` ", "```inline");
|
||||||
|
assert("``````inline`````` ", "```inline```");
|
||||||
|
assert("```inline`````` ", "inline```");
|
||||||
|
assert!("```inline".as_value().is_none());
|
||||||
|
assert!("```inline``` ne".as_value().is_none());
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ fn gemtext() {
|
||||||
// Parse document by line
|
// Parse document by line
|
||||||
for line in gemtext.lines() {
|
for line in gemtext.lines() {
|
||||||
// Inline code
|
// Inline code
|
||||||
if let Some(result) = Inline::from(line) {
|
if let Some(result) = Inline::parse(line) {
|
||||||
code_inline.push(result);
|
code_inline.push(result);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue