tml/src/tag.rs

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)
}
}
}