use std::collections::BTreeMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum NodeType {
Text,
Element,
Heading,
Paragraph,
Div,
Blockquote,
Pre,
Hr,
List,
ListItem,
DefinitionList,
DefinitionTerm,
DefinitionDescription,
Table,
TableRow,
TableCell,
TableHeader,
TableBody,
TableHead,
TableFoot,
Link,
Image,
Strong,
Em,
Code,
Strikethrough,
Underline,
Subscript,
Superscript,
Mark,
Small,
Br,
Span,
Article,
Section,
Nav,
Aside,
Header,
Footer,
Main,
Figure,
Figcaption,
Time,
Details,
Summary,
Form,
Input,
Select,
Option,
Button,
Textarea,
Label,
Fieldset,
Legend,
Audio,
Video,
Picture,
Source,
Iframe,
Svg,
Canvas,
Ruby,
Rt,
Rp,
Abbr,
Kbd,
Samp,
Var,
Cite,
Q,
Del,
Ins,
Data,
Meter,
Progress,
Output,
Template,
Slot,
Html,
Head,
Body,
Title,
Meta,
LinkTag,
Style,
Script,
Base,
Custom,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NodeContext {
pub node_type: NodeType,
pub tag_name: String,
pub attributes: BTreeMap<String, String>,
pub depth: usize,
pub index_in_parent: usize,
pub parent_tag: Option<String>,
pub is_inline: bool,
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum VisitResult {
#[default]
Continue,
Custom(String),
Skip,
PreserveHtml,
Error(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_type_equality() {
assert_eq!(NodeType::Text, NodeType::Text);
assert_ne!(NodeType::Text, NodeType::Element);
assert_eq!(NodeType::Heading, NodeType::Heading);
}
#[test]
fn test_node_context_creation() {
let ctx = NodeContext {
node_type: NodeType::Heading,
tag_name: "h1".to_string(),
attributes: BTreeMap::new(),
depth: 1,
index_in_parent: 0,
parent_tag: Some("body".to_string()),
is_inline: false,
};
assert_eq!(ctx.node_type, NodeType::Heading);
assert_eq!(ctx.tag_name, "h1");
assert_eq!(ctx.depth, 1);
assert!(!ctx.is_inline);
}
#[test]
fn test_visit_result_variants() {
let continue_result = VisitResult::Continue;
matches!(continue_result, VisitResult::Continue);
let custom_result = VisitResult::Custom("# Custom Output".to_string());
if let VisitResult::Custom(output) = custom_result {
assert_eq!(output, "# Custom Output");
}
let skip_result = VisitResult::Skip;
matches!(skip_result, VisitResult::Skip);
let preserve_result = VisitResult::PreserveHtml;
matches!(preserve_result, VisitResult::PreserveHtml);
let error_result = VisitResult::Error("Test error".to_string());
if let VisitResult::Error(msg) = error_result {
assert_eq!(msg, "Test error");
}
}
}