mirror of
https://github.com/YGGverse/ggemtext.git
synced 2026-03-31 17:15:33 +00:00
remove regex dependency, rename constructor, implement Gemtext trait
This commit is contained in:
parent
9d27cdfb49
commit
7802869d0d
2 changed files with 70 additions and 20 deletions
|
|
@ -1,4 +1,8 @@
|
|||
use glib::{Regex, RegexCompileFlags, RegexMatchFlags};
|
||||
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) tag
|
||||
/// * store as entire static chars array
|
||||
pub const TAG_H1: &str = "#";
|
||||
pub const TAG_H2: &str = "##";
|
||||
pub const TAG_H3: &str = "###";
|
||||
|
||||
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) type holder
|
||||
pub enum Level {
|
||||
|
|
@ -9,32 +13,78 @@ pub enum Level {
|
|||
|
||||
/// [Header](https://geminiprotocol.net/docs/gemtext-specification.gmi#heading-lines) entity holder
|
||||
pub struct Header {
|
||||
pub value: String,
|
||||
pub level: Level,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
// Constructors
|
||||
|
||||
/// Parse `Self` from line string
|
||||
pub fn from(line: &str) -> Option<Self> {
|
||||
// Parse line
|
||||
let regex = Regex::split_simple(
|
||||
r"^(#{1,3})\s*(.+)$",
|
||||
line,
|
||||
RegexCompileFlags::DEFAULT,
|
||||
RegexMatchFlags::DEFAULT,
|
||||
);
|
||||
|
||||
// Result
|
||||
pub fn parse(line: &str) -> Option<Self> {
|
||||
Some(Self {
|
||||
level: match regex.get(1)?.len() {
|
||||
1 => Level::H1,
|
||||
2 => Level::H2,
|
||||
3 => Level::H3,
|
||||
_ => return None,
|
||||
},
|
||||
value: regex.get(2)?.trim().to_string(),
|
||||
level: line.to_level()?,
|
||||
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(&self.level)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Gemtext {
|
||||
/// Get [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) value from `Self`
|
||||
fn as_value(&self) -> Option<&Self>;
|
||||
/// Convert `Self` to `Level`
|
||||
fn to_level(&self) -> Option<Level>;
|
||||
/// Convert `Self` to [Gemtext](https://geminiprotocol.net/docs/gemtext-specification.gmi) line
|
||||
fn to_source(&self, level: &Level) -> String;
|
||||
}
|
||||
|
||||
impl Gemtext for str {
|
||||
fn as_value(&self) -> Option<&Self> {
|
||||
if let Some(h3) = self.strip_prefix(TAG_H3) {
|
||||
if h3.trim_start().starts_with(TAG_H1) {
|
||||
return None; // H4+
|
||||
}
|
||||
return Some(h3.trim());
|
||||
}
|
||||
if let Some(h2) = self.strip_prefix(TAG_H2) {
|
||||
return Some(h2.trim());
|
||||
}
|
||||
if let Some(h1) = self.strip_prefix(TAG_H1) {
|
||||
return Some(h1.trim());
|
||||
}
|
||||
None
|
||||
}
|
||||
fn to_level(&self) -> Option<Level> {
|
||||
if let Some(h3) = self.strip_prefix(TAG_H3) {
|
||||
if h3.trim_start().starts_with(TAG_H1) {
|
||||
return None; // H4+
|
||||
}
|
||||
return Some(Level::H3);
|
||||
}
|
||||
if self.starts_with(TAG_H2) {
|
||||
return Some(Level::H2);
|
||||
}
|
||||
if self.starts_with(TAG_H1) {
|
||||
return Some(Level::H1);
|
||||
}
|
||||
None
|
||||
}
|
||||
fn to_source(&self, level: &Level) -> String {
|
||||
format!(
|
||||
"{} {}",
|
||||
match level {
|
||||
Level::H1 => TAG_H1,
|
||||
Level::H2 => TAG_H2,
|
||||
Level::H3 => TAG_H3,
|
||||
},
|
||||
self.trim()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue