forked from mars/tml
115 lines
2.4 KiB
Rust
115 lines
2.4 KiB
Rust
use std::str::FromStr;
|
|
use strum::EnumString;
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, EnumString)]
|
|
#[strum(serialize_all = "kebab-case", ascii_case_insensitive)]
|
|
pub enum TextTagKind {
|
|
Plain,
|
|
Italic,
|
|
Bold,
|
|
Underline,
|
|
Strikethrough,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub enum TextNode {
|
|
Text(String),
|
|
Tag(TextTag),
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub struct TextTag {
|
|
pub kind: TextTagKind,
|
|
pub children: Vec<TextNode>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, EnumString)]
|
|
#[strum(serialize_all = "kebab-case", ascii_case_insensitive)]
|
|
pub enum LeafTagKind {
|
|
Figlet,
|
|
Code,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub struct LeafTag {
|
|
pub kind: LeafTagKind,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq, EnumString)]
|
|
#[strum(serialize_all = "kebab-case", ascii_case_insensitive)]
|
|
pub enum BlockTagKind {
|
|
H1,
|
|
H2,
|
|
H3,
|
|
P,
|
|
Ul,
|
|
Ol,
|
|
Li,
|
|
Div,
|
|
Table,
|
|
Tr,
|
|
Td,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub enum BlockNode {
|
|
Text(TextTag),
|
|
Leaf(LeafTag),
|
|
Block(BlockTag),
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub struct BlockTag {
|
|
pub kind: BlockTagKind,
|
|
pub children: Vec<BlockNode>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
|
pub enum AnyTagKind {
|
|
Text(TextTagKind),
|
|
Leaf(LeafTagKind),
|
|
Block(BlockTagKind),
|
|
}
|
|
|
|
impl AnyTagKind {
|
|
pub fn as_text(self) -> Option<TextTagKind> {
|
|
if let AnyTagKind::Text(text) = self {
|
|
Some(text)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn as_leaf(self) -> Option<LeafTagKind> {
|
|
if let AnyTagKind::Leaf(leaf) = self {
|
|
Some(leaf)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
pub fn as_block(self) -> Option<BlockTagKind> {
|
|
if let AnyTagKind::Block(block) = self {
|
|
Some(block)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromStr for AnyTagKind {
|
|
type Err = strum::ParseError;
|
|
|
|
fn from_str(string: &str) -> Result<Self, strum::ParseError> {
|
|
if let Ok(text) = TextTagKind::from_str(string) {
|
|
Ok(AnyTagKind::Text(text))
|
|
} else if let Ok(leaf) = LeafTagKind::from_str(string) {
|
|
Ok(AnyTagKind::Leaf(leaf))
|
|
} else if let Ok(block) = BlockTagKind::from_str(string) {
|
|
Ok(AnyTagKind::Block(block))
|
|
} else {
|
|
Err(strum::ParseError::VariantNotFound)
|
|
}
|
|
}
|
|
}
|