1use crate::unist::Position;
14use alloc::{
15 fmt,
16 string::{String, ToString},
17 vec::Vec,
18};
19
20mod headings;
21pub use headings::{HeadingEntry, HeadingOptions, Headings};
22mod code;
23pub use code::Code;
24mod code_fence;
25pub use code_fence::CodeFence;
26mod frontmatter;
27pub use frontmatter::Frontmatter;
28
29pub type Stop = (usize, usize);
32
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35#[cfg_attr(
36 feature = "serde",
37 derive(serde::Serialize, serde::Deserialize),
38 serde(rename_all = "lowercase")
39)]
40pub enum ReferenceKind {
41 Shortcut,
43 Collapsed,
45 Full,
47}
48
49#[derive(Clone, Copy, Debug, Eq, PartialEq)]
53pub enum AlignKind {
54 Left,
64 Right,
74 Center,
84 None,
94}
95
96#[cfg(feature = "serde")]
98impl serde::ser::Serialize for AlignKind {
99 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
100 where
101 S: serde::ser::Serializer,
102 {
103 match self {
104 AlignKind::Left => serializer.serialize_unit_variant("AlignKind", 0, "left"),
105 AlignKind::Right => serializer.serialize_unit_variant("AlignKind", 1, "right"),
106 AlignKind::Center => serializer.serialize_unit_variant("AlignKind", 2, "center"),
107 AlignKind::None => serializer.serialize_none(),
108 }
109 }
110}
111
112#[cfg(feature = "serde")]
113struct AlignKindVisitor;
114
115#[cfg(feature = "serde")]
116impl serde::de::Visitor<'_> for AlignKindVisitor {
117 type Value = AlignKind;
118
119 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
120 formatter.write_str("'left', 'right', 'center' or null")
121 }
122
123 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
124 where
125 E: serde::de::Error,
126 {
127 match v {
128 "left" => Ok(AlignKind::Left),
129 "right" => Ok(AlignKind::Right),
130 "center" => Ok(AlignKind::Center),
131 &_ => Err(serde::de::Error::invalid_type(
132 serde::de::Unexpected::Str(v),
133 &self,
134 )),
135 }
136 }
137
138 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
139 where
140 E: serde::de::Error,
141 {
142 match v {
143 b"left" => Ok(AlignKind::Left),
144 b"right" => Ok(AlignKind::Right),
145 b"center" => Ok(AlignKind::Center),
146 &_ => Err(serde::de::Error::invalid_type(
147 serde::de::Unexpected::Bytes(v),
148 &self,
149 )),
150 }
151 }
152
153 fn visit_none<E>(self) -> Result<Self::Value, E>
154 where
155 E: serde::de::Error,
156 {
157 Ok(AlignKind::None)
158 }
159
160 fn visit_unit<E>(self) -> Result<Self::Value, E>
161 where
162 E: serde::de::Error,
163 {
164 Ok(AlignKind::None)
165 }
166}
167
168#[cfg(feature = "serde")]
169impl<'de> serde::de::Deserialize<'de> for AlignKind {
170 fn deserialize<D>(deserializer: D) -> Result<AlignKind, D::Error>
171 where
172 D: serde::de::Deserializer<'de>,
173 {
174 deserializer.deserialize_any(AlignKindVisitor)
175 }
176}
177
178#[derive(Clone, Eq, PartialEq)]
180#[cfg_attr(
181 feature = "serde",
182 derive(serde::Serialize, serde::Deserialize),
183 serde(tag = "type", rename_all = "camelCase")
184)]
185pub enum Node {
186 Root(Root),
189
190 Fragment(Fragment),
195 Blockquote(Blockquote),
197 FootnoteDefinition(FootnoteDefinition),
199 MdxJsxFlowElement(MdxJsxFlowElement),
201 List(List),
203
204 Frontmatter(Frontmatter),
207 MdxjsEsm(MdxjsEsm),
209 Toml(Toml),
211 Yaml(Yaml),
213
214 Break(Break),
217 InlineCode(InlineCode),
219 InlineMath(InlineMath),
221 Delete(Delete),
223 Emphasis(Emphasis),
225 MdxTextExpression(MdxTextExpression),
227 FootnoteReference(FootnoteReference),
229 Html(Html),
231 Image(Image),
233 ImageReference(ImageReference),
235 MdxJsxTextElement(MdxJsxTextElement),
237 Link(Link),
239 LinkReference(LinkReference),
241 Strong(Strong),
243 Text(Text),
245
246 Code(Code),
249 Math(Math),
251 MdxFlowExpression(MdxFlowExpression),
253 Heading(Heading),
255 Table(Table),
259 ThematicBreak(ThematicBreak),
261
262 TableRow(TableRow),
265
266 TableCell(TableCell),
269
270 ListItem(ListItem),
273
274 Definition(Definition),
277 Paragraph(Paragraph),
279}
280
281impl fmt::Debug for Node {
282 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 match self {
285 Node::Root(x) => x.fmt(f),
286 Node::Fragment(x) => x.fmt(f),
287 Node::Blockquote(x) => x.fmt(f),
288 Node::FootnoteDefinition(x) => x.fmt(f),
289 Node::MdxJsxFlowElement(x) => x.fmt(f),
290 Node::List(x) => x.fmt(f),
291 Node::MdxjsEsm(x) => x.fmt(f),
292 Node::Toml(x) => x.fmt(f),
293 Node::Frontmatter(x) => x.fmt(f),
294 Node::Yaml(x) => x.fmt(f),
295 Node::Break(x) => x.fmt(f),
296 Node::InlineCode(x) => x.fmt(f),
297 Node::InlineMath(x) => x.fmt(f),
298 Node::Delete(x) => x.fmt(f),
299 Node::Emphasis(x) => x.fmt(f),
300 Node::MdxTextExpression(x) => x.fmt(f),
301 Node::FootnoteReference(x) => x.fmt(f),
302 Node::Html(x) => x.fmt(f),
303 Node::Image(x) => x.fmt(f),
304 Node::ImageReference(x) => x.fmt(f),
305 Node::MdxJsxTextElement(x) => x.fmt(f),
306 Node::Link(x) => x.fmt(f),
307 Node::LinkReference(x) => x.fmt(f),
308 Node::Strong(x) => x.fmt(f),
309 Node::Text(x) => x.fmt(f),
310 Node::Code(x) => x.fmt(f),
311 Node::Math(x) => x.fmt(f),
312 Node::MdxFlowExpression(x) => x.fmt(f),
313 Node::Heading(x) => x.fmt(f),
314 Node::Table(x) => x.fmt(f),
315 Node::ThematicBreak(x) => x.fmt(f),
316 Node::TableRow(x) => x.fmt(f),
317 Node::TableCell(x) => x.fmt(f),
318 Node::ListItem(x) => x.fmt(f),
319 Node::Definition(x) => x.fmt(f),
320 Node::Paragraph(x) => x.fmt(f),
321 }
322 }
323}
324
325fn children_to_string(children: &[Node]) -> String {
326 children.iter().map(ToString::to_string).collect()
327}
328
329#[allow(clippy::to_string_trait_impl)]
331impl ToString for Node {
332 fn to_string(&self) -> String {
333 match self {
334 Node::Root(x) => children_to_string(&x.children),
336 Node::Fragment(x) => children_to_string(&x.children),
337 Node::Blockquote(x) => children_to_string(&x.children),
338 Node::FootnoteDefinition(x) => children_to_string(&x.children),
339 Node::MdxJsxFlowElement(x) => children_to_string(&x.children),
340 Node::List(x) => children_to_string(&x.children),
341 Node::Delete(x) => children_to_string(&x.children),
342 Node::Emphasis(x) => children_to_string(&x.children),
343 Node::MdxJsxTextElement(x) => children_to_string(&x.children),
344 Node::Link(x) => children_to_string(&x.children),
345 Node::LinkReference(x) => children_to_string(&x.children),
346 Node::Strong(x) => children_to_string(&x.children),
347 Node::Heading(x) => children_to_string(&x.children),
348 Node::Table(x) => children_to_string(&x.children),
349 Node::TableRow(x) => children_to_string(&x.children),
350 Node::TableCell(x) => children_to_string(&x.children),
351 Node::ListItem(x) => children_to_string(&x.children),
352 Node::Paragraph(x) => children_to_string(&x.children),
353
354 Node::MdxjsEsm(x) => x.value.clone(),
356 Node::Toml(x) => x.value.clone(),
357 Node::Frontmatter(x) => x.value.clone(),
358 Node::Yaml(x) => x.value.clone(),
359 Node::InlineCode(x) => x.value.clone(),
360 Node::InlineMath(x) => x.value.clone(),
361 Node::MdxTextExpression(x) => x.value.clone(),
362 Node::Html(x) => x.value.clone(),
363 Node::Text(x) => x.value.clone(),
364 Node::Code(x) => x.value.clone(),
365 Node::Math(x) => x.value.clone(),
366 Node::MdxFlowExpression(x) => x.value.clone(),
367
368 Node::Break(_)
370 | Node::FootnoteReference(_)
371 | Node::Image(_)
372 | Node::ImageReference(_)
373 | Node::ThematicBreak(_)
374 | Node::Definition(_) => String::new(),
375 }
376 }
377}
378
379impl Node {
380 #[must_use]
381 pub fn children(&self) -> Option<&Vec<Node>> {
382 match self {
383 Node::Root(x) => Some(&x.children),
385 Node::Fragment(x) => Some(&x.children),
386 Node::Paragraph(x) => Some(&x.children),
387 Node::Heading(x) => Some(&x.children),
388 Node::Blockquote(x) => Some(&x.children),
389 Node::List(x) => Some(&x.children),
390 Node::ListItem(x) => Some(&x.children),
391 Node::Emphasis(x) => Some(&x.children),
392 Node::Strong(x) => Some(&x.children),
393 Node::Link(x) => Some(&x.children),
394 Node::LinkReference(x) => Some(&x.children),
395 Node::FootnoteDefinition(x) => Some(&x.children),
396 Node::Table(x) => Some(&x.children),
397 Node::TableRow(x) => Some(&x.children),
398 Node::TableCell(x) => Some(&x.children),
399 Node::Delete(x) => Some(&x.children),
400 Node::MdxJsxFlowElement(x) => Some(&x.children),
401 Node::MdxJsxTextElement(x) => Some(&x.children),
402 _ => None,
404 }
405 }
406
407 pub fn children_mut(&mut self) -> Option<&mut Vec<Node>> {
408 match self {
409 Node::Root(x) => Some(&mut x.children),
411 Node::Fragment(x) => Some(&mut x.children),
412 Node::Paragraph(x) => Some(&mut x.children),
413 Node::Heading(x) => Some(&mut x.children),
414 Node::Blockquote(x) => Some(&mut x.children),
415 Node::List(x) => Some(&mut x.children),
416 Node::ListItem(x) => Some(&mut x.children),
417 Node::Emphasis(x) => Some(&mut x.children),
418 Node::Strong(x) => Some(&mut x.children),
419 Node::Link(x) => Some(&mut x.children),
420 Node::LinkReference(x) => Some(&mut x.children),
421 Node::FootnoteDefinition(x) => Some(&mut x.children),
422 Node::Table(x) => Some(&mut x.children),
423 Node::TableRow(x) => Some(&mut x.children),
424 Node::TableCell(x) => Some(&mut x.children),
425 Node::Delete(x) => Some(&mut x.children),
426 Node::MdxJsxFlowElement(x) => Some(&mut x.children),
427 Node::MdxJsxTextElement(x) => Some(&mut x.children),
428 _ => None,
430 }
431 }
432
433 #[must_use]
434 pub fn position(&self) -> Option<&Position> {
435 match self {
436 Node::Root(x) => x.position.as_ref(),
437 Node::Fragment(_) => None,
438 Node::Blockquote(x) => x.position.as_ref(),
439 Node::FootnoteDefinition(x) => x.position.as_ref(),
440 Node::MdxJsxFlowElement(x) => x.position.as_ref(),
441 Node::List(x) => x.position.as_ref(),
442 Node::MdxjsEsm(x) => x.position.as_ref(),
443 Node::Toml(x) => x.position.as_ref(),
444 Node::Frontmatter(x) => x.position.as_ref(),
445 Node::Yaml(x) => x.position.as_ref(),
446 Node::Break(x) => x.position.as_ref(),
447 Node::InlineCode(x) => x.position.as_ref(),
448 Node::InlineMath(x) => x.position.as_ref(),
449 Node::Delete(x) => x.position.as_ref(),
450 Node::Emphasis(x) => x.position.as_ref(),
451 Node::MdxTextExpression(x) => x.position.as_ref(),
452 Node::FootnoteReference(x) => x.position.as_ref(),
453 Node::Html(x) => x.position.as_ref(),
454 Node::Image(x) => x.position.as_ref(),
455 Node::ImageReference(x) => x.position.as_ref(),
456 Node::MdxJsxTextElement(x) => x.position.as_ref(),
457 Node::Link(x) => x.position.as_ref(),
458 Node::LinkReference(x) => x.position.as_ref(),
459 Node::Strong(x) => x.position.as_ref(),
460 Node::Text(x) => x.position.as_ref(),
461 Node::Code(x) => x.position.as_ref(),
462 Node::Math(x) => x.position.as_ref(),
463 Node::MdxFlowExpression(x) => x.position.as_ref(),
464 Node::Heading(x) => x.position.as_ref(),
465 Node::Table(x) => x.position.as_ref(),
466 Node::ThematicBreak(x) => x.position.as_ref(),
467 Node::TableRow(x) => x.position.as_ref(),
468 Node::TableCell(x) => x.position.as_ref(),
469 Node::ListItem(x) => x.position.as_ref(),
470 Node::Definition(x) => x.position.as_ref(),
471 Node::Paragraph(x) => x.position.as_ref(),
472 }
473 }
474
475 pub fn position_mut(&mut self) -> Option<&mut Position> {
476 match self {
477 Node::Root(x) => x.position.as_mut(),
478 Node::Fragment(_) => None,
479 Node::Blockquote(x) => x.position.as_mut(),
480 Node::FootnoteDefinition(x) => x.position.as_mut(),
481 Node::MdxJsxFlowElement(x) => x.position.as_mut(),
482 Node::List(x) => x.position.as_mut(),
483 Node::MdxjsEsm(x) => x.position.as_mut(),
484 Node::Toml(x) => x.position.as_mut(),
485 Node::Frontmatter(x) => x.position.as_mut(),
486 Node::Yaml(x) => x.position.as_mut(),
487 Node::Break(x) => x.position.as_mut(),
488 Node::InlineCode(x) => x.position.as_mut(),
489 Node::InlineMath(x) => x.position.as_mut(),
490 Node::Delete(x) => x.position.as_mut(),
491 Node::Emphasis(x) => x.position.as_mut(),
492 Node::MdxTextExpression(x) => x.position.as_mut(),
493 Node::FootnoteReference(x) => x.position.as_mut(),
494 Node::Html(x) => x.position.as_mut(),
495 Node::Image(x) => x.position.as_mut(),
496 Node::ImageReference(x) => x.position.as_mut(),
497 Node::MdxJsxTextElement(x) => x.position.as_mut(),
498 Node::Link(x) => x.position.as_mut(),
499 Node::LinkReference(x) => x.position.as_mut(),
500 Node::Strong(x) => x.position.as_mut(),
501 Node::Text(x) => x.position.as_mut(),
502 Node::Code(x) => x.position.as_mut(),
503 Node::Math(x) => x.position.as_mut(),
504 Node::MdxFlowExpression(x) => x.position.as_mut(),
505 Node::Heading(x) => x.position.as_mut(),
506 Node::Table(x) => x.position.as_mut(),
507 Node::ThematicBreak(x) => x.position.as_mut(),
508 Node::TableRow(x) => x.position.as_mut(),
509 Node::TableCell(x) => x.position.as_mut(),
510 Node::ListItem(x) => x.position.as_mut(),
511 Node::Definition(x) => x.position.as_mut(),
512 Node::Paragraph(x) => x.position.as_mut(),
513 }
514 }
515
516 pub fn position_set(&mut self, position: Option<Position>) {
517 match self {
518 Node::Root(x) => x.position = position,
519 Node::Fragment(_) => (),
520 Node::Blockquote(x) => x.position = position,
521 Node::FootnoteDefinition(x) => x.position = position,
522 Node::MdxJsxFlowElement(x) => x.position = position,
523 Node::List(x) => x.position = position,
524 Node::MdxjsEsm(x) => x.position = position,
525 Node::Toml(x) => x.position = position,
526 Node::Frontmatter(x) => x.position = position,
527 Node::Yaml(x) => x.position = position,
528 Node::Break(x) => x.position = position,
529 Node::InlineCode(x) => x.position = position,
530 Node::InlineMath(x) => x.position = position,
531 Node::Delete(x) => x.position = position,
532 Node::Emphasis(x) => x.position = position,
533 Node::MdxTextExpression(x) => x.position = position,
534 Node::FootnoteReference(x) => x.position = position,
535 Node::Html(x) => x.position = position,
536 Node::Image(x) => x.position = position,
537 Node::ImageReference(x) => x.position = position,
538 Node::MdxJsxTextElement(x) => x.position = position,
539 Node::Link(x) => x.position = position,
540 Node::LinkReference(x) => x.position = position,
541 Node::Strong(x) => x.position = position,
542 Node::Text(x) => x.position = position,
543 Node::Code(x) => x.position = position,
544 Node::Math(x) => x.position = position,
545 Node::MdxFlowExpression(x) => x.position = position,
546 Node::Heading(x) => x.position = position,
547 Node::Table(x) => x.position = position,
548 Node::ThematicBreak(x) => x.position = position,
549 Node::TableRow(x) => x.position = position,
550 Node::TableCell(x) => x.position = position,
551 Node::ListItem(x) => x.position = position,
552 Node::Definition(x) => x.position = position,
553 Node::Paragraph(x) => x.position = position,
554 }
555 }
556
557 pub fn walk<'a>(&'a self, mut visitor: impl FnMut(&'a Node)) {
559 fn visit<'a>(node: &'a Node, visitor: &mut impl FnMut(&'a Node)) {
560 visitor(node);
561 if let Some(children) = node.children() {
562 for child in children {
563 visit(child, visitor);
564 }
565 }
566 }
567
568 visit(self, &mut visitor);
569 }
570
571 pub fn walk_mut(&mut self, mut visitor: impl FnMut(&mut Node)) {
573 fn visit(node: &mut Node, visitor: &mut impl FnMut(&mut Node)) {
574 visitor(node);
575 if let Some(children) = node.children_mut() {
576 for child in children {
577 visit(child, visitor);
578 }
579 }
580 }
581
582 visit(self, &mut visitor);
583 }
584
585 #[must_use]
590 pub fn text_content(&self) -> String {
591 match self {
592 Node::Image(node) => node.alt.clone(),
593 Node::ImageReference(node) => node.alt.clone(),
594 Node::Break(_) => "\n".into(),
595 Node::Definition(_) | Node::FootnoteReference(_) | Node::ThematicBreak(_) => {
596 String::new()
597 }
598 _ => {
599 if let Some(children) = self.children() {
600 children.iter().map(Node::text_content).collect()
601 } else {
602 self.to_string()
603 }
604 }
605 }
606 }
607
608 #[must_use]
610 pub fn find_heading(&self, title: &str) -> Option<&Node> {
611 self.children()?
612 .iter()
613 .find(|child| matches!(child, Node::Heading(_)) && child.text_content() == title)
614 }
615
616 #[must_use]
618 pub fn code_language(&self) -> Option<&str> {
619 match self {
620 Node::InlineCode(node) => node.lang.as_deref(),
621 Node::Code(node) => node.lang.as_deref(),
622 Node::Frontmatter(node) => node.language(),
623 _ => None,
624 }
625 }
626
627 #[must_use]
634 pub fn code_fence(&self) -> Option<CodeFence> {
635 match self {
636 Node::Code(node) => node.fence,
637 Node::Frontmatter(node) => Some(CodeFence {
638 character: node.fence,
639 length: node.fence_length,
640 indent: 0,
641 }),
642 Node::Yaml(_) => Some(CodeFence {
643 character: '-',
644 length: 3,
645 indent: 0,
646 }),
647 Node::Toml(_) => Some(CodeFence {
648 character: '+',
649 length: 3,
650 indent: 0,
651 }),
652 _ => None,
653 }
654 }
655
656 #[must_use]
662 pub fn code_info(&self) -> Option<String> {
663 match self {
664 Node::InlineCode(node) => node.lang.clone(),
665 Node::Frontmatter(node) => Some(node.info.clone()),
666 Node::Code(node) => match (&node.lang, &node.meta) {
667 (Some(lang), Some(meta)) => Some(alloc::format!("{lang} {meta}")),
668 (Some(lang), None) => Some(lang.clone()),
669 (None, Some(meta)) => Some(meta.clone()),
670 (None, None) => None,
671 },
672 _ => None,
673 }
674 }
675
676 pub fn extract_children(&mut self) -> Option<Node> {
682 self.children_mut().map(|children| {
683 Node::Fragment(Fragment {
684 children: core::mem::take(children),
685 })
686 })
687 }
688
689 pub fn render_with<R: crate::renderer::Renderer>(&self, renderer: &mut R) -> String {
691 renderer.render(self)
692 }
693
694 #[must_use]
705 pub fn to_markdown(&self) -> String {
706 crate::markdown::to_markdown(self).expect("Markdown serialization failed for this AST node")
707 }
708
709 pub fn to_markdown_with_options(
716 &self,
717 options: &crate::markdown::Options,
718 ) -> Result<String, crate::message::Message> {
719 crate::markdown::to_markdown_with_options(self, options)
720 }
721
722 pub fn replace_heading_section(
730 &mut self,
731 heading_index: usize,
732 replacement: Vec<Node>,
733 replace_heading: bool,
734 remove_subsections: bool,
735 ) -> bool {
736 let Some(children) = self.children_mut() else {
737 return false;
738 };
739 let depth = match children.get(heading_index) {
740 Some(Node::Heading(heading)) => heading.depth,
741 _ => return false,
742 };
743 let end = children
744 .iter()
745 .enumerate()
746 .skip(heading_index + 1)
747 .find_map(|(index, node)| {
748 let Node::Heading(next) = node else {
749 return None;
750 };
751 if !remove_subsections || next.depth <= depth {
752 Some(index)
753 } else {
754 None
755 }
756 })
757 .unwrap_or(children.len());
758 let start = if replace_heading {
759 heading_index
760 } else {
761 heading_index + 1
762 };
763
764 children.splice(start..end, replacement);
765 true
766 }
767}
768
769#[derive(Clone, Debug, Eq, PartialEq)]
771#[cfg_attr(
772 feature = "serde",
773 derive(serde::Serialize, serde::Deserialize),
774 serde(untagged)
775)]
776pub enum AttributeContent {
777 Expression(MdxJsxExpressionAttribute),
784 Property(MdxJsxAttribute),
791}
792#[derive(Clone, Debug, Eq, PartialEq)]
794#[cfg_attr(
795 feature = "serde",
796 derive(serde::Serialize, serde::Deserialize),
797 serde(tag = "type", rename = "mdxJsxAttributeValueExpression")
798)]
799pub struct AttributeValueExpression {
800 pub value: String,
801 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
802 pub stops: Vec<Stop>,
803}
804
805#[derive(Clone, Debug, Eq, PartialEq)]
807#[cfg_attr(
808 feature = "serde",
809 derive(serde::Serialize, serde::Deserialize),
810 serde(untagged)
811)]
812pub enum AttributeValue {
813 Expression(AttributeValueExpression),
820 Literal(String),
827}
828
829#[derive(Clone, Debug, Eq, PartialEq)]
834#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
835pub struct Fragment {
836 pub children: Vec<Node>,
838}
839
840#[derive(Clone, Debug, Eq, PartialEq)]
847#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
848pub struct Root {
849 pub children: Vec<Node>,
852 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
854 pub position: Option<Position>,
855}
856
857#[derive(Clone, Debug, Eq, PartialEq)]
864#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
865pub struct Paragraph {
866 pub children: Vec<Node>,
869 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
871 pub position: Option<Position>,
872}
873
874#[derive(Clone, Debug, Eq, PartialEq)]
881#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
882pub struct Heading {
883 pub children: Vec<Node>,
886 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
888 pub position: Option<Position>,
889 pub depth: u8,
892}
893
894#[derive(Clone, Debug, Eq, PartialEq)]
901#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
902pub struct ThematicBreak {
903 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
906 pub position: Option<Position>,
907}
908
909#[derive(Clone, Debug, Eq, PartialEq)]
916#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
917pub struct Blockquote {
918 pub children: Vec<Node>,
921 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
923 pub position: Option<Position>,
924}
925
926#[derive(Clone, Debug, Eq, PartialEq)]
933#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
934pub struct List {
935 pub children: Vec<Node>,
938 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
940 pub position: Option<Position>,
941 pub ordered: bool,
944 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
947 pub start: Option<u32>,
948 pub spread: bool,
951}
952
953#[derive(Clone, Debug, Eq, PartialEq)]
960#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
961pub struct ListItem {
962 pub children: Vec<Node>,
965 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
967 pub position: Option<Position>,
968 pub spread: bool,
972 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
975 pub checked: Option<bool>,
976}
977
978#[derive(Clone, Debug, Eq, PartialEq)]
985#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
986pub struct Html {
987 pub value: String,
990 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
992 pub position: Option<Position>,
993}
994
995#[derive(Clone, Debug, Eq, PartialEq)]
1006#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1007pub struct Math {
1008 pub value: String,
1011 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1013 pub position: Option<Position>,
1014 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1017 pub meta: Option<String>,
1018}
1019
1020#[derive(Clone, Debug, Eq, PartialEq)]
1027#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1028pub struct Definition {
1029 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1032 pub position: Option<Position>,
1033 pub url: String,
1036 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1039 pub title: Option<String>,
1040 pub identifier: String,
1046 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1053 pub label: Option<String>,
1054}
1055
1056#[derive(Clone, Debug, Eq, PartialEq)]
1063#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1064pub struct Text {
1065 pub value: String,
1068 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1070 pub position: Option<Position>,
1071}
1072
1073#[derive(Clone, Debug, Eq, PartialEq)]
1080#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1081pub struct Emphasis {
1082 pub children: Vec<Node>,
1085 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1087 pub position: Option<Position>,
1088}
1089
1090#[derive(Clone, Debug, Eq, PartialEq)]
1097#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1098pub struct Strong {
1099 pub children: Vec<Node>,
1102 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1104 pub position: Option<Position>,
1105}
1106
1107#[derive(Clone, Debug, Eq, PartialEq)]
1114#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1115pub struct InlineCode {
1116 pub value: String,
1119 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1121 pub position: Option<Position>,
1122 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1127 pub lang: Option<String>,
1128}
1129
1130#[derive(Clone, Debug, Eq, PartialEq)]
1137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1138pub struct InlineMath {
1139 pub value: String,
1142 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1144 pub position: Option<Position>,
1145}
1146
1147#[derive(Clone, Debug, Eq, PartialEq)]
1155#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1156pub struct Break {
1157 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1160 pub position: Option<Position>,
1161}
1162
1163#[derive(Clone, Debug, Eq, PartialEq)]
1170#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1171pub struct Link {
1172 pub children: Vec<Node>,
1175 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1177 pub position: Option<Position>,
1178 pub url: String,
1181 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1184 pub title: Option<String>,
1185}
1186
1187#[derive(Clone, Debug, Eq, PartialEq)]
1194#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1195pub struct Image {
1196 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1199 pub position: Option<Position>,
1200 pub alt: String,
1204 pub url: String,
1207 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1210 pub title: Option<String>,
1211}
1212
1213#[derive(Clone, Debug, Eq, PartialEq)]
1220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1221pub struct LinkReference {
1222 pub children: Vec<Node>,
1225 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1227 pub position: Option<Position>,
1228 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))]
1231 pub reference_kind: ReferenceKind,
1232 pub identifier: String,
1238 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1245 pub label: Option<String>,
1246}
1247
1248#[derive(Clone, Debug, Eq, PartialEq)]
1255#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1256pub struct ImageReference {
1257 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1260 pub position: Option<Position>,
1261 pub alt: String,
1265 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))]
1268 pub reference_kind: ReferenceKind,
1269 pub identifier: String,
1275 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1282 pub label: Option<String>,
1283}
1284
1285#[derive(Clone, Debug, Eq, PartialEq)]
1292#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1293pub struct FootnoteDefinition {
1294 pub children: Vec<Node>,
1297 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1299 pub position: Option<Position>,
1300 pub identifier: String,
1306 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1313 pub label: Option<String>,
1314}
1315
1316#[derive(Clone, Debug, Eq, PartialEq)]
1323#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1324pub struct FootnoteReference {
1325 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1328 pub position: Option<Position>,
1329 pub identifier: String,
1335 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1342 pub label: Option<String>,
1343}
1344
1345#[derive(Clone, Debug, Eq, PartialEq)]
1354#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1355pub struct Table {
1356 pub children: Vec<Node>,
1359 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1361 pub position: Option<Position>,
1362 pub align: Vec<AlignKind>,
1365}
1366
1367#[derive(Clone, Debug, Eq, PartialEq)]
1374#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1375pub struct TableRow {
1376 pub children: Vec<Node>,
1379 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1381 pub position: Option<Position>,
1382}
1383
1384#[derive(Clone, Debug, Eq, PartialEq)]
1391#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1392pub struct TableCell {
1393 pub children: Vec<Node>,
1396 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1398 pub position: Option<Position>,
1399}
1400
1401#[derive(Clone, Debug, Eq, PartialEq)]
1408#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1409pub struct Delete {
1410 pub children: Vec<Node>,
1413 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1415 pub position: Option<Position>,
1416}
1417
1418#[derive(Clone, Debug, Eq, PartialEq)]
1429#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1430pub struct Yaml {
1431 pub value: String,
1434 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1436 pub position: Option<Position>,
1437}
1438
1439#[derive(Clone, Debug, Eq, PartialEq)]
1450#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1451pub struct Toml {
1452 pub value: String,
1455 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1457 pub position: Option<Position>,
1458}
1459
1460#[derive(Clone, Debug, Eq, PartialEq)]
1467#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1468pub struct MdxjsEsm {
1469 pub value: String,
1472 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1474 pub position: Option<Position>,
1475
1476 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1478 pub stops: Vec<Stop>,
1479}
1480
1481#[derive(Clone, Debug, Eq, PartialEq)]
1488#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1489pub struct MdxFlowExpression {
1490 pub value: String,
1493 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1495 pub position: Option<Position>,
1496
1497 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1499 pub stops: Vec<Stop>,
1500}
1501
1502#[derive(Clone, Debug, Eq, PartialEq)]
1509#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1510pub struct MdxTextExpression {
1511 pub value: String,
1514 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1516 pub position: Option<Position>,
1517
1518 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1520 pub stops: Vec<Stop>,
1521}
1522
1523#[derive(Clone, Debug, Eq, PartialEq)]
1530#[cfg_attr(
1531 feature = "serde",
1532 derive(serde::Serialize, serde::Deserialize),
1533 serde(rename_all = "camelCase")
1534)]
1535pub struct MdxJsxFlowElement {
1536 pub children: Vec<Node>,
1539 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1541 pub position: Option<Position>,
1542 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1547 pub name: Option<String>,
1548 pub attributes: Vec<AttributeContent>,
1550}
1551
1552#[derive(Clone, Debug, Eq, PartialEq)]
1559#[cfg_attr(
1560 feature = "serde",
1561 derive(serde::Serialize, serde::Deserialize),
1562 serde(rename_all = "camelCase")
1563)]
1564pub struct MdxJsxTextElement {
1565 pub children: Vec<Node>,
1568 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1570 pub position: Option<Position>,
1571 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1576 pub name: Option<String>,
1577 pub attributes: Vec<AttributeContent>,
1579}
1580
1581#[derive(Clone, Debug, Eq, PartialEq)]
1588#[cfg_attr(
1589 feature = "serde",
1590 derive(serde::Serialize, serde::Deserialize),
1591 serde(tag = "type", rename = "mdxJsxAttribute")
1592)]
1593pub struct MdxJsxAttribute {
1594 pub name: String,
1599 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1601 pub value: Option<AttributeValue>,
1602}
1603
1604#[derive(Clone, Debug, Eq, PartialEq)]
1611#[cfg_attr(
1612 feature = "serde",
1613 derive(serde::Serialize, serde::Deserialize),
1614 serde(tag = "type", rename = "mdxJsxExpressionAttribute")
1615)]
1616pub struct MdxJsxExpressionAttribute {
1617 pub value: String,
1619 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1621 pub stops: Vec<Stop>,
1622}
1623
1624#[cfg(test)]
1625mod tests {
1626 use super::*;
1627 use crate::unist::Position;
1628 use alloc::{format, string::ToString, vec};
1629
1630 #[test]
1633 fn text() {
1634 let mut node = Node::Text(Text {
1635 value: "a".into(),
1636 position: None,
1637 });
1638
1639 assert_eq!(
1640 format!("{node:?}"),
1641 "Text { value: \"a\", position: None }",
1642 "should support `Debug`"
1643 );
1644 assert_eq!(node.to_string(), "a", "should support `ToString`");
1645 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1646 assert_eq!(node.children(), None, "should support `children`");
1647 assert_eq!(node.position(), None, "should support `position`");
1648 assert_eq!(node.position_mut(), None, "should support `position`");
1649 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1650 assert_eq!(
1651 format!("{node:?}"),
1652 "Text { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1653 "should support `position_set`"
1654 );
1655 }
1656
1657 #[test]
1658 fn inline_code() {
1659 let mut node = Node::InlineCode(InlineCode {
1660 value: "a".into(),
1661 position: None,
1662 lang: None,
1663 });
1664
1665 assert_eq!(
1666 format!("{node:?}"),
1667 "InlineCode { value: \"a\", position: None, lang: None }",
1668 "should support `Debug`"
1669 );
1670 assert_eq!(node.to_string(), "a", "should support `ToString`");
1671 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1672 assert_eq!(node.children(), None, "should support `children`");
1673 assert_eq!(node.position(), None, "should support `position`");
1674 assert_eq!(node.position_mut(), None, "should support `position`");
1675 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1676 assert_eq!(
1677 format!("{node:?}"),
1678 "InlineCode { value: \"a\", position: Some(1:1-1:2 (0-1)), lang: None }",
1679 "should support `position_set`"
1680 );
1681 }
1682
1683 #[test]
1684 fn code() {
1685 let mut node = Node::Code(Code {
1686 fence: None,
1687 value: "a".into(),
1688 position: None,
1689 lang: None,
1690 meta: None,
1691 });
1692
1693 assert_eq!(
1694 format!("{node:?}"),
1695 "Code { value: \"a\", position: None, lang: None, meta: None, fence: None }",
1696 "should support `Debug`"
1697 );
1698 assert_eq!(node.to_string(), "a", "should support `ToString`");
1699 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1700 assert_eq!(node.children(), None, "should support `children`");
1701 assert_eq!(node.position(), None, "should support `position`");
1702 assert_eq!(node.position_mut(), None, "should support `position`");
1703 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1704 assert_eq!(
1705 format!("{node:?}"),
1706 "Code { value: \"a\", position: Some(1:1-1:2 (0-1)), lang: None, meta: None, fence: None }",
1707 "should support `position_set`"
1708 );
1709 }
1710
1711 #[test]
1712 fn inline_math() {
1713 let mut node = Node::InlineMath(InlineMath {
1714 value: "a".into(),
1715 position: None,
1716 });
1717
1718 assert_eq!(
1719 format!("{node:?}"),
1720 "InlineMath { value: \"a\", position: None }",
1721 "should support `Debug`"
1722 );
1723 assert_eq!(node.to_string(), "a", "should support `ToString`");
1724 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1725 assert_eq!(node.children(), None, "should support `children`");
1726 assert_eq!(node.position(), None, "should support `position`");
1727 assert_eq!(node.position_mut(), None, "should support `position`");
1728 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1729 assert_eq!(
1730 format!("{node:?}"),
1731 "InlineMath { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1732 "should support `position_set`"
1733 );
1734 }
1735
1736 #[test]
1737 fn math() {
1738 let mut node = Node::Math(Math {
1739 value: "a".into(),
1740 position: None,
1741 meta: None,
1742 });
1743
1744 assert_eq!(
1745 format!("{node:?}"),
1746 "Math { value: \"a\", position: None, meta: None }",
1747 "should support `Debug`"
1748 );
1749 assert_eq!(node.to_string(), "a", "should support `ToString`");
1750 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1751 assert_eq!(node.children(), None, "should support `children`");
1752 assert_eq!(node.position(), None, "should support `position`");
1753 assert_eq!(node.position_mut(), None, "should support `position`");
1754 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1755 assert_eq!(
1756 format!("{node:?}"),
1757 "Math { value: \"a\", position: Some(1:1-1:2 (0-1)), meta: None }",
1758 "should support `position_set`"
1759 );
1760 }
1761
1762 #[test]
1763 fn html() {
1764 let mut node = Node::Html(Html {
1765 value: "a".into(),
1766 position: None,
1767 });
1768
1769 assert_eq!(
1770 format!("{node:?}"),
1771 "Html { value: \"a\", position: None }",
1772 "should support `Debug`"
1773 );
1774 assert_eq!(node.to_string(), "a", "should support `ToString`");
1775 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1776 assert_eq!(node.children(), None, "should support `children`");
1777 assert_eq!(node.position(), None, "should support `position`");
1778 assert_eq!(node.position_mut(), None, "should support `position`");
1779 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1780 assert_eq!(
1781 format!("{node:?}"),
1782 "Html { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1783 "should support `position_set`"
1784 );
1785 }
1786
1787 #[test]
1788 fn mdx_text_expression() {
1789 let mut node = Node::MdxTextExpression(MdxTextExpression {
1790 value: "a".into(),
1791 stops: vec![],
1792 position: None,
1793 });
1794
1795 assert_eq!(
1796 format!("{node:?}"),
1797 "MdxTextExpression { value: \"a\", position: None, stops: [] }",
1798 "should support `Debug`"
1799 );
1800 assert_eq!(node.to_string(), "a", "should support `ToString`");
1801 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1802 assert_eq!(node.children(), None, "should support `children`");
1803 assert_eq!(node.position(), None, "should support `position`");
1804 assert_eq!(node.position_mut(), None, "should support `position`");
1805 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1806 assert_eq!(
1807 format!("{node:?}"),
1808 "MdxTextExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1809 "should support `position_set`"
1810 );
1811 }
1812
1813 #[test]
1814 fn mdx_flow_expression() {
1815 let mut node = Node::MdxFlowExpression(MdxFlowExpression {
1816 value: "a".into(),
1817 stops: vec![],
1818 position: None,
1819 });
1820
1821 assert_eq!(
1822 format!("{node:?}"),
1823 "MdxFlowExpression { value: \"a\", position: None, stops: [] }",
1824 "should support `Debug`"
1825 );
1826 assert_eq!(node.to_string(), "a", "should support `ToString`");
1827 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1828 assert_eq!(node.children(), None, "should support `children`");
1829 assert_eq!(node.position(), None, "should support `position`");
1830 assert_eq!(node.position_mut(), None, "should support `position`");
1831 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1832 assert_eq!(
1833 format!("{node:?}"),
1834 "MdxFlowExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1835 "should support `position_set`"
1836 );
1837 }
1838
1839 #[test]
1840 fn mdxjs_esm() {
1841 let mut node = Node::MdxjsEsm(MdxjsEsm {
1842 value: "a".into(),
1843 stops: vec![],
1844 position: None,
1845 });
1846
1847 assert_eq!(
1848 format!("{node:?}"),
1849 "MdxjsEsm { value: \"a\", position: None, stops: [] }",
1850 "should support `Debug`"
1851 );
1852 assert_eq!(node.to_string(), "a", "should support `ToString`");
1853 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1854 assert_eq!(node.children(), None, "should support `children`");
1855 assert_eq!(node.position(), None, "should support `position`");
1856 assert_eq!(node.position_mut(), None, "should support `position`");
1857 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1858 assert_eq!(
1859 format!("{node:?}"),
1860 "MdxjsEsm { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1861 "should support `position_set`"
1862 );
1863 }
1864
1865 #[test]
1866 fn toml() {
1867 let mut node = Node::Toml(Toml {
1868 value: "a".into(),
1869 position: None,
1870 });
1871
1872 assert_eq!(
1873 format!("{node:?}"),
1874 "Toml { value: \"a\", position: None }",
1875 "should support `Debug`"
1876 );
1877 assert_eq!(node.to_string(), "a", "should support `ToString`");
1878 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1879 assert_eq!(node.children(), None, "should support `children`");
1880 assert_eq!(node.position(), None, "should support `position`");
1881 assert_eq!(node.position_mut(), None, "should support `position`");
1882 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1883 assert_eq!(
1884 format!("{node:?}"),
1885 "Toml { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1886 "should support `position_set`"
1887 );
1888 }
1889
1890 #[test]
1891 fn yaml() {
1892 let mut node = Node::Yaml(Yaml {
1893 value: "a".into(),
1894 position: None,
1895 });
1896
1897 assert_eq!(
1898 format!("{node:?}"),
1899 "Yaml { value: \"a\", position: None }",
1900 "should support `Debug`"
1901 );
1902 assert_eq!(node.to_string(), "a", "should support `ToString`");
1903 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1904 assert_eq!(node.children(), None, "should support `children`");
1905 assert_eq!(node.position(), None, "should support `position`");
1906 assert_eq!(node.position_mut(), None, "should support `position`");
1907 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1908 assert_eq!(
1909 format!("{node:?}"),
1910 "Yaml { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1911 "should support `position_set`"
1912 );
1913 }
1914
1915 #[test]
1918 fn break_node() {
1919 let mut node = Node::Break(Break { position: None });
1920
1921 assert_eq!(
1922 format!("{node:?}"),
1923 "Break { position: None }",
1924 "should support `Debug`"
1925 );
1926 assert_eq!(node.to_string(), "", "should support `ToString`");
1927 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1928 assert_eq!(node.children(), None, "should support `children`");
1929 assert_eq!(node.position(), None, "should support `position`");
1930 assert_eq!(node.position_mut(), None, "should support `position`");
1931 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1932 assert_eq!(
1933 format!("{node:?}"),
1934 "Break { position: Some(1:1-1:2 (0-1)) }",
1935 "should support `position_set`"
1936 );
1937 }
1938
1939 #[test]
1940 fn thematic_break() {
1941 let mut node = Node::ThematicBreak(ThematicBreak { position: None });
1942
1943 assert_eq!(
1944 format!("{node:?}"),
1945 "ThematicBreak { position: None }",
1946 "should support `Debug`"
1947 );
1948 assert_eq!(node.to_string(), "", "should support `ToString`");
1949 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1950 assert_eq!(node.children(), None, "should support `children`");
1951 assert_eq!(node.position(), None, "should support `position`");
1952 assert_eq!(node.position_mut(), None, "should support `position`");
1953 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1954 assert_eq!(
1955 format!("{node:?}"),
1956 "ThematicBreak { position: Some(1:1-1:2 (0-1)) }",
1957 "should support `position_set`"
1958 );
1959 }
1960
1961 #[test]
1962 fn footnote_reference() {
1963 let mut node = Node::FootnoteReference(FootnoteReference {
1964 position: None,
1965 identifier: "a".into(),
1966 label: Some("b".into()),
1967 });
1968
1969 assert_eq!(
1970 format!("{node:?}"),
1971 "FootnoteReference { position: None, identifier: \"a\", label: Some(\"b\") }",
1972 "should support `Debug`"
1973 );
1974 assert_eq!(node.to_string(), "", "should support `ToString`");
1975 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1976 assert_eq!(node.children(), None, "should support `children`");
1977 assert_eq!(node.position(), None, "should support `position`");
1978 assert_eq!(node.position_mut(), None, "should support `position`");
1979 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1980 assert_eq!(
1981 format!("{node:?}"),
1982 "FootnoteReference { position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: Some(\"b\") }",
1983 "should support `position_set`"
1984 );
1985 }
1986
1987 #[test]
1988 fn image_reference() {
1989 let mut node = Node::ImageReference(ImageReference {
1990 position: None,
1991 alt: "a".into(),
1992 identifier: "b".into(),
1993 label: Some("c".into()),
1994 reference_kind: ReferenceKind::Full,
1995 });
1996
1997 assert_eq!(
1998 format!("{node:?}"),
1999 "ImageReference { position: None, alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }",
2000 "should support `Debug`"
2001 );
2002 assert_eq!(node.to_string(), "", "should support `ToString`");
2003 assert_eq!(node.children_mut(), None, "should support `children_mut`");
2004 assert_eq!(node.children(), None, "should support `children`");
2005 assert_eq!(node.position(), None, "should support `position`");
2006 assert_eq!(node.position_mut(), None, "should support `position`");
2007 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2008 assert_eq!(
2009 format!("{node:?}"),
2010 "ImageReference { position: Some(1:1-1:2 (0-1)), alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }",
2011 "should support `position_set`"
2012 );
2013 }
2014
2015 #[test]
2016 fn image() {
2017 let mut node = Node::Image(Image {
2018 position: None,
2019 alt: "a".into(),
2020 url: "b".into(),
2021 title: None,
2022 });
2023
2024 assert_eq!(
2025 format!("{node:?}"),
2026 "Image { position: None, alt: \"a\", url: \"b\", title: None }",
2027 "should support `Debug`"
2028 );
2029 assert_eq!(node.to_string(), "", "should support `ToString`");
2030 assert_eq!(node.children_mut(), None, "should support `children_mut`");
2031 assert_eq!(node.children(), None, "should support `children`");
2032 assert_eq!(node.position(), None, "should support `position`");
2033 assert_eq!(node.position_mut(), None, "should support `position`");
2034 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2035 assert_eq!(
2036 format!("{node:?}"),
2037 "Image { position: Some(1:1-1:2 (0-1)), alt: \"a\", url: \"b\", title: None }",
2038 "should support `position_set`"
2039 );
2040 }
2041
2042 #[test]
2043 fn definition() {
2044 let mut node = Node::Definition(Definition {
2045 position: None,
2046 identifier: "a".into(),
2047 label: None,
2048 url: "b".into(),
2049 title: None,
2050 });
2051
2052 assert_eq!(
2053 format!("{node:?}"),
2054 "Definition { position: None, url: \"b\", title: None, identifier: \"a\", label: None }",
2055 "should support `Debug`"
2056 );
2057 assert_eq!(node.to_string(), "", "should support `ToString`");
2058 assert_eq!(node.children_mut(), None, "should support `children_mut`");
2059 assert_eq!(node.children(), None, "should support `children`");
2060 assert_eq!(node.position(), None, "should support `position`");
2061 assert_eq!(node.position_mut(), None, "should support `position`");
2062 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2063 assert_eq!(
2064 format!("{node:?}"),
2065 "Definition { position: Some(1:1-1:2 (0-1)), url: \"b\", title: None, identifier: \"a\", label: None }",
2066 "should support `position_set`"
2067 );
2068 }
2069
2070 #[test]
2073 fn root() {
2074 let mut node = Node::Root(Root {
2075 position: None,
2076 children: vec![],
2077 });
2078
2079 assert_eq!(
2080 format!("{node:?}"),
2081 "Root { children: [], position: None }",
2082 "should support `Debug`"
2083 );
2084 assert_eq!(node.to_string(), "", "should support `ToString`");
2085 assert_eq!(
2086 node.children_mut(),
2087 Some(&mut vec![]),
2088 "should support `children_mut`"
2089 );
2090 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2091 assert_eq!(node.position(), None, "should support `position`");
2092 assert_eq!(node.position_mut(), None, "should support `position`");
2093 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2094 assert_eq!(
2095 format!("{node:?}"),
2096 "Root { children: [], position: Some(1:1-1:2 (0-1)) }",
2097 "should support `position_set`"
2098 );
2099 }
2100
2101 #[test]
2102 fn block_quote() {
2103 let mut node = Node::Blockquote(Blockquote {
2104 position: None,
2105 children: vec![],
2106 });
2107
2108 assert_eq!(
2109 format!("{node:?}"),
2110 "Blockquote { children: [], position: None }",
2111 "should support `Debug`"
2112 );
2113 assert_eq!(node.to_string(), "", "should support `ToString`");
2114 assert_eq!(
2115 node.children_mut(),
2116 Some(&mut vec![]),
2117 "should support `children_mut`"
2118 );
2119 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2120 assert_eq!(node.position(), None, "should support `position`");
2121 assert_eq!(node.position_mut(), None, "should support `position`");
2122 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2123 assert_eq!(
2124 format!("{node:?}"),
2125 "Blockquote { children: [], position: Some(1:1-1:2 (0-1)) }",
2126 "should support `position_set`"
2127 );
2128 }
2129
2130 #[test]
2131 fn delete() {
2132 let mut node = Node::Delete(Delete {
2133 position: None,
2134 children: vec![],
2135 });
2136
2137 assert_eq!(
2138 format!("{node:?}"),
2139 "Delete { children: [], position: None }",
2140 "should support `Debug`"
2141 );
2142 assert_eq!(node.to_string(), "", "should support `ToString`");
2143 assert_eq!(
2144 node.children_mut(),
2145 Some(&mut vec![]),
2146 "should support `children_mut`"
2147 );
2148 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2149 assert_eq!(node.position(), None, "should support `position`");
2150 assert_eq!(node.position_mut(), None, "should support `position`");
2151 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2152 assert_eq!(
2153 format!("{node:?}"),
2154 "Delete { children: [], position: Some(1:1-1:2 (0-1)) }",
2155 "should support `position_set`"
2156 );
2157 }
2158
2159 #[test]
2160 fn emphasis() {
2161 let mut node = Node::Emphasis(Emphasis {
2162 position: None,
2163 children: vec![],
2164 });
2165
2166 assert_eq!(
2167 format!("{node:?}"),
2168 "Emphasis { children: [], position: None }",
2169 "should support `Debug`"
2170 );
2171 assert_eq!(node.to_string(), "", "should support `ToString`");
2172 assert_eq!(
2173 node.children_mut(),
2174 Some(&mut vec![]),
2175 "should support `children_mut`"
2176 );
2177 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2178 assert_eq!(node.position(), None, "should support `position`");
2179 assert_eq!(node.position_mut(), None, "should support `position`");
2180 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2181 assert_eq!(
2182 format!("{node:?}"),
2183 "Emphasis { children: [], position: Some(1:1-1:2 (0-1)) }",
2184 "should support `position_set`"
2185 );
2186 }
2187
2188 #[test]
2189 fn strong() {
2190 let mut node = Node::Strong(Strong {
2191 position: None,
2192 children: vec![],
2193 });
2194
2195 assert_eq!(
2196 format!("{node:?}"),
2197 "Strong { children: [], position: None }",
2198 "should support `Debug`"
2199 );
2200 assert_eq!(node.to_string(), "", "should support `ToString`");
2201 assert_eq!(
2202 node.children_mut(),
2203 Some(&mut vec![]),
2204 "should support `children_mut`"
2205 );
2206 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2207 assert_eq!(node.position(), None, "should support `position`");
2208 assert_eq!(node.position_mut(), None, "should support `position`");
2209 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2210 assert_eq!(
2211 format!("{node:?}"),
2212 "Strong { children: [], position: Some(1:1-1:2 (0-1)) }",
2213 "should support `position_set`"
2214 );
2215 }
2216
2217 #[test]
2218 fn paragraph() {
2219 let mut node = Node::Paragraph(Paragraph {
2220 position: None,
2221 children: vec![],
2222 });
2223
2224 assert_eq!(
2225 format!("{node:?}"),
2226 "Paragraph { children: [], position: None }",
2227 "should support `Debug`"
2228 );
2229 assert_eq!(node.to_string(), "", "should support `ToString`");
2230 assert_eq!(
2231 node.children_mut(),
2232 Some(&mut vec![]),
2233 "should support `children_mut`"
2234 );
2235 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2236 assert_eq!(node.position(), None, "should support `position`");
2237 assert_eq!(node.position_mut(), None, "should support `position`");
2238 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2239 assert_eq!(
2240 format!("{node:?}"),
2241 "Paragraph { children: [], position: Some(1:1-1:2 (0-1)) }",
2242 "should support `position_set`"
2243 );
2244 }
2245
2246 #[test]
2247 fn table_row() {
2248 let mut node = Node::TableRow(TableRow {
2249 position: None,
2250 children: vec![],
2251 });
2252
2253 assert_eq!(
2254 format!("{node:?}"),
2255 "TableRow { children: [], position: None }",
2256 "should support `Debug`"
2257 );
2258 assert_eq!(node.to_string(), "", "should support `ToString`");
2259 assert_eq!(
2260 node.children_mut(),
2261 Some(&mut vec![]),
2262 "should support `children_mut`"
2263 );
2264 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2265 assert_eq!(node.position(), None, "should support `position`");
2266 assert_eq!(node.position_mut(), None, "should support `position`");
2267 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2268 assert_eq!(
2269 format!("{node:?}"),
2270 "TableRow { children: [], position: Some(1:1-1:2 (0-1)) }",
2271 "should support `position_set`"
2272 );
2273 }
2274
2275 #[test]
2276 fn table_cell() {
2277 let mut node = Node::TableCell(TableCell {
2278 position: None,
2279 children: vec![],
2280 });
2281
2282 assert_eq!(
2283 format!("{node:?}"),
2284 "TableCell { children: [], position: None }",
2285 "should support `Debug`"
2286 );
2287 assert_eq!(node.to_string(), "", "should support `ToString`");
2288 assert_eq!(
2289 node.children_mut(),
2290 Some(&mut vec![]),
2291 "should support `children_mut`"
2292 );
2293 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2294 assert_eq!(node.position(), None, "should support `position`");
2295 assert_eq!(node.position_mut(), None, "should support `position`");
2296 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2297 assert_eq!(
2298 format!("{node:?}"),
2299 "TableCell { children: [], position: Some(1:1-1:2 (0-1)) }",
2300 "should support `position_set`"
2301 );
2302 }
2303
2304 #[test]
2305 fn heading() {
2306 let mut node = Node::Heading(Heading {
2307 position: None,
2308 depth: 1,
2309 children: vec![],
2310 });
2311
2312 assert_eq!(
2313 format!("{node:?}"),
2314 "Heading { children: [], position: None, depth: 1 }",
2315 "should support `Debug`"
2316 );
2317 assert_eq!(node.to_string(), "", "should support `ToString`");
2318 assert_eq!(
2319 node.children_mut(),
2320 Some(&mut vec![]),
2321 "should support `children_mut`"
2322 );
2323 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2324 assert_eq!(node.position(), None, "should support `position`");
2325 assert_eq!(node.position_mut(), None, "should support `position`");
2326 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2327 assert_eq!(
2328 format!("{node:?}"),
2329 "Heading { children: [], position: Some(1:1-1:2 (0-1)), depth: 1 }",
2330 "should support `position_set`"
2331 );
2332 }
2333
2334 #[test]
2335 fn table() {
2336 let mut node = Node::Table(Table {
2337 position: None,
2338 align: vec![],
2339 children: vec![],
2340 });
2341
2342 assert_eq!(
2343 format!("{node:?}"),
2344 "Table { children: [], position: None, align: [] }",
2345 "should support `Debug`"
2346 );
2347 assert_eq!(node.to_string(), "", "should support `ToString`");
2348 assert_eq!(
2349 node.children_mut(),
2350 Some(&mut vec![]),
2351 "should support `children_mut`"
2352 );
2353 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2354 assert_eq!(node.position(), None, "should support `position`");
2355 assert_eq!(node.position_mut(), None, "should support `position`");
2356 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2357 assert_eq!(
2358 format!("{node:?}"),
2359 "Table { children: [], position: Some(1:1-1:2 (0-1)), align: [] }",
2360 "should support `position_set`"
2361 );
2362 }
2363
2364 #[test]
2365 fn list_item() {
2366 let mut node = Node::ListItem(ListItem {
2367 position: None,
2368 spread: false,
2369 checked: None,
2370 children: vec![],
2371 });
2372
2373 assert_eq!(
2374 format!("{node:?}"),
2375 "ListItem { children: [], position: None, spread: false, checked: None }",
2376 "should support `Debug`"
2377 );
2378 assert_eq!(node.to_string(), "", "should support `ToString`");
2379 assert_eq!(
2380 node.children_mut(),
2381 Some(&mut vec![]),
2382 "should support `children_mut`"
2383 );
2384 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2385 assert_eq!(node.position(), None, "should support `position`");
2386 assert_eq!(node.position_mut(), None, "should support `position`");
2387 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2388 assert_eq!(
2389 format!("{node:?}"),
2390 "ListItem { children: [], position: Some(1:1-1:2 (0-1)), spread: false, checked: None }",
2391 "should support `position_set`"
2392 );
2393 }
2394
2395 #[test]
2396 fn list() {
2397 let mut node = Node::List(List {
2398 position: None,
2399 spread: false,
2400 ordered: false,
2401 start: None,
2402 children: vec![],
2403 });
2404
2405 assert_eq!(
2406 format!("{node:?}"),
2407 "List { children: [], position: None, ordered: false, start: None, spread: false }",
2408 "should support `Debug`"
2409 );
2410 assert_eq!(node.to_string(), "", "should support `ToString`");
2411 assert_eq!(
2412 node.children_mut(),
2413 Some(&mut vec![]),
2414 "should support `children_mut`"
2415 );
2416 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2417 assert_eq!(node.position(), None, "should support `position`");
2418 assert_eq!(node.position_mut(), None, "should support `position`");
2419 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2420 assert_eq!(
2421 format!("{node:?}"),
2422 "List { children: [], position: Some(1:1-1:2 (0-1)), ordered: false, start: None, spread: false }",
2423 "should support `position_set`"
2424 );
2425 }
2426
2427 #[test]
2428 fn link_reference() {
2429 let mut node = Node::LinkReference(LinkReference {
2430 position: None,
2431 identifier: "a".into(),
2432 label: None,
2433 reference_kind: ReferenceKind::Full,
2434 children: vec![],
2435 });
2436
2437 assert_eq!(
2438 format!("{node:?}"),
2439 "LinkReference { children: [], position: None, reference_kind: Full, identifier: \"a\", label: None }",
2440 "should support `Debug`"
2441 );
2442 assert_eq!(node.to_string(), "", "should support `ToString`");
2443 assert_eq!(
2444 node.children_mut(),
2445 Some(&mut vec![]),
2446 "should support `children_mut`"
2447 );
2448 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2449 assert_eq!(node.position(), None, "should support `position`");
2450 assert_eq!(node.position_mut(), None, "should support `position`");
2451 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2452 assert_eq!(
2453 format!("{node:?}"),
2454 "LinkReference { children: [], position: Some(1:1-1:2 (0-1)), reference_kind: Full, identifier: \"a\", label: None }",
2455 "should support `position_set`"
2456 );
2457 }
2458
2459 #[test]
2460 fn link() {
2461 let mut node = Node::Link(Link {
2462 position: None,
2463 url: "a".into(),
2464 title: None,
2465 children: vec![],
2466 });
2467
2468 assert_eq!(
2469 format!("{node:?}"),
2470 "Link { children: [], position: None, url: \"a\", title: None }",
2471 "should support `Debug`"
2472 );
2473 assert_eq!(node.to_string(), "", "should support `ToString`");
2474 assert_eq!(
2475 node.children_mut(),
2476 Some(&mut vec![]),
2477 "should support `children_mut`"
2478 );
2479 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2480 assert_eq!(node.position(), None, "should support `position`");
2481 assert_eq!(node.position_mut(), None, "should support `position`");
2482 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2483 assert_eq!(
2484 format!("{node:?}"),
2485 "Link { children: [], position: Some(1:1-1:2 (0-1)), url: \"a\", title: None }",
2486 "should support `position_set`"
2487 );
2488 }
2489
2490 #[test]
2491 fn footnote_definition() {
2492 let mut node = Node::FootnoteDefinition(FootnoteDefinition {
2493 position: None,
2494 identifier: "a".into(),
2495 label: None,
2496 children: vec![],
2497 });
2498
2499 assert_eq!(
2500 format!("{node:?}"),
2501 "FootnoteDefinition { children: [], position: None, identifier: \"a\", label: None }",
2502 "should support `Debug`"
2503 );
2504 assert_eq!(node.to_string(), "", "should support `ToString`");
2505 assert_eq!(
2506 node.children_mut(),
2507 Some(&mut vec![]),
2508 "should support `children_mut`"
2509 );
2510 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2511 assert_eq!(node.position(), None, "should support `position`");
2512 assert_eq!(node.position_mut(), None, "should support `position`");
2513 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2514 assert_eq!(
2515 format!("{node:?}"),
2516 "FootnoteDefinition { children: [], position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: None }",
2517 "should support `position_set`"
2518 );
2519 }
2520
2521 #[test]
2522 fn mdx_jsx_flow_element() {
2523 let mut node = Node::MdxJsxFlowElement(MdxJsxFlowElement {
2524 position: None,
2525 name: None,
2526 attributes: vec![],
2527 children: vec![],
2528 });
2529
2530 assert_eq!(
2531 format!("{node:?}"),
2532 "MdxJsxFlowElement { children: [], position: None, name: None, attributes: [] }",
2533 "should support `Debug`"
2534 );
2535 assert_eq!(node.to_string(), "", "should support `ToString`");
2536 assert_eq!(
2537 node.children_mut(),
2538 Some(&mut vec![]),
2539 "should support `children_mut`"
2540 );
2541 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2542 assert_eq!(node.position(), None, "should support `position`");
2543 assert_eq!(node.position_mut(), None, "should support `position`");
2544 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2545 assert_eq!(
2546 format!("{node:?}"),
2547 "MdxJsxFlowElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }",
2548 "should support `position_set`"
2549 );
2550 }
2551
2552 #[test]
2553 fn mdx_jsx_text_element() {
2554 let mut node = Node::MdxJsxTextElement(MdxJsxTextElement {
2555 position: None,
2556 name: None,
2557 attributes: vec![],
2558 children: vec![],
2559 });
2560
2561 assert_eq!(
2562 format!("{node:?}"),
2563 "MdxJsxTextElement { children: [], position: None, name: None, attributes: [] }",
2564 "should support `Debug`"
2565 );
2566 assert_eq!(node.to_string(), "", "should support `ToString`");
2567 assert_eq!(
2568 node.children_mut(),
2569 Some(&mut vec![]),
2570 "should support `children_mut`"
2571 );
2572 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2573 assert_eq!(node.position(), None, "should support `position`");
2574 assert_eq!(node.position_mut(), None, "should support `position`");
2575 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2576 assert_eq!(
2577 format!("{node:?}"),
2578 "MdxJsxTextElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }",
2579 "should support `position_set`"
2580 );
2581 }
2582
2583 #[test]
2584 fn fragment_node_methods() {
2585 let text = Node::Text(Text {
2586 value: "fragment".into(),
2587 position: None,
2588 });
2589 let mut node = Node::Fragment(Fragment {
2590 children: vec![text],
2591 });
2592
2593 assert_eq!(
2594 format!("{node:?}"),
2595 "Fragment { children: [Text { value: \"fragment\", position: None }] }"
2596 );
2597 assert_eq!(node.to_string(), "fragment");
2598 assert_eq!(node.children().map(Vec::len), Some(1));
2599 assert_eq!(node.position(), None);
2600 assert_eq!(node.position_mut(), None);
2601 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2602 assert_eq!(node.position(), None);
2603
2604 let extracted = node.extract_children().expect("extract fragment children");
2605 assert_eq!(extracted.to_string(), "fragment");
2606 assert_eq!(node.children().unwrap(), &[]);
2607 assert!(node.extract_children().is_some());
2608 }
2609
2610 #[test]
2611 fn walks_and_mutates_nested_children() {
2612 let mut node = Node::Root(Root {
2613 position: None,
2614 children: vec![Node::Paragraph(Paragraph {
2615 position: None,
2616 children: vec![Node::Text(Text {
2617 value: "before".into(),
2618 position: None,
2619 })],
2620 })],
2621 });
2622
2623 let mut visited = Vec::new();
2624 node.walk(|node| visited.push(node.to_string()));
2625 assert_eq!(visited, ["before", "before", "before"]);
2626
2627 node.walk_mut(|node| {
2628 if let Node::Text(text) = node {
2629 text.value.push_str(" after");
2630 }
2631 });
2632 assert_eq!(node.text_content(), "before after");
2633 }
2634
2635 #[test]
2636 fn node_text_and_heading_helpers() {
2637 let image = Node::Image(Image {
2638 position: None,
2639 alt: "image alt".into(),
2640 url: "image.png".into(),
2641 title: None,
2642 });
2643 let image_reference = Node::ImageReference(ImageReference {
2644 position: None,
2645 alt: "reference alt".into(),
2646 reference_kind: ReferenceKind::Full,
2647 identifier: "image".into(),
2648 label: None,
2649 });
2650 let heading = Node::Heading(Heading {
2651 position: None,
2652 depth: 2,
2653 children: vec![Node::Text(Text {
2654 value: "Target".into(),
2655 position: None,
2656 })],
2657 });
2658 let root = Node::Root(Root {
2659 position: None,
2660 children: vec![image.clone(), image_reference.clone(), heading.clone()],
2661 });
2662
2663 assert_eq!(image.text_content(), "image alt");
2664 assert_eq!(image_reference.text_content(), "reference alt");
2665 assert_eq!(Node::Break(Break { position: None }).text_content(), "\n");
2666 assert_eq!(
2667 Node::ThematicBreak(ThematicBreak { position: None }).text_content(),
2668 ""
2669 );
2670 assert_eq!(
2671 Node::Definition(Definition {
2672 position: None,
2673 identifier: "x".into(),
2674 label: None,
2675 url: "x".into(),
2676 title: None
2677 })
2678 .text_content(),
2679 ""
2680 );
2681 assert_eq!(root.find_heading("Target"), Some(&heading));
2682 assert_eq!(root.find_heading("missing"), None);
2683 assert_eq!(image.find_heading("Target"), None);
2684 assert_eq!(
2685 Node::Text(Text {
2686 value: "x".into(),
2687 position: None
2688 })
2689 .code_language(),
2690 None
2691 );
2692 }
2693
2694 #[test]
2695 fn code_accessors_cover_optional_metadata() {
2696 let inline = Node::InlineCode(InlineCode {
2697 value: "code".into(),
2698 position: None,
2699 lang: Some("rust".into()),
2700 });
2701 assert_eq!(inline.code_language(), Some("rust"));
2702 assert_eq!(inline.code_info().as_deref(), Some("rust"));
2703
2704 for (lang, meta, expected) in [
2705 (Some("rust"), Some("ignore"), Some("rust ignore")),
2706 (Some("rust"), None, Some("rust")),
2707 (None, Some("ignore"), Some("ignore")),
2708 (None, None, None),
2709 ] {
2710 let code = Node::Code(Code {
2711 fence: None,
2712 value: "code".into(),
2713 position: None,
2714 lang: lang.map(Into::into),
2715 meta: meta.map(Into::into),
2716 });
2717 assert_eq!(code.code_language(), lang);
2718 assert_eq!(code.code_info().as_deref(), expected);
2719 }
2720
2721 assert_eq!(
2722 Node::Text(Text {
2723 value: "plain".into(),
2724 position: None,
2725 })
2726 .code_info(),
2727 None
2728 );
2729 }
2730
2731 #[test]
2732 fn node_serializes_markdown_with_custom_options() {
2733 let node = Node::Text(Text {
2734 value: "text".into(),
2735 position: None,
2736 });
2737 let options = crate::markdown::Options::default();
2738
2739 assert_eq!(node.to_markdown_with_options(&options).unwrap(), "text\n");
2740 }
2741
2742 #[test]
2743 fn replaces_heading_sections_with_all_options() {
2744 let heading = |depth, title: &str| {
2745 Node::Heading(Heading {
2746 position: None,
2747 depth,
2748 children: vec![Node::Text(Text {
2749 value: title.into(),
2750 position: None,
2751 })],
2752 })
2753 };
2754 let text = |value: &str| {
2755 Node::Text(Text {
2756 value: value.into(),
2757 position: None,
2758 })
2759 };
2760 let replacement = || vec![text("replacement")];
2761
2762 let mut root = Node::Root(Root {
2763 position: None,
2764 children: vec![
2765 heading(1, "one"),
2766 text("body"),
2767 heading(2, "nested"),
2768 text("nested body"),
2769 heading(1, "two"),
2770 ],
2771 });
2772 assert!(!root.replace_heading_section(1, replacement(), true, false));
2773 assert!(!text("not a parent").replace_heading_section(0, replacement(), true, false));
2774 assert!(root.replace_heading_section(0, replacement(), false, true));
2775 assert_eq!(root.to_string(), "onereplacementtwo");
2776
2777 let mut root = Node::Root(Root {
2778 position: None,
2779 children: vec![
2780 heading(1, "one"),
2781 text("body"),
2782 heading(2, "nested"),
2783 text("nested body"),
2784 heading(1, "two"),
2785 ],
2786 });
2787 assert!(root.replace_heading_section(0, replacement(), true, false));
2788 assert_eq!(root.to_string(), "replacementnestednested bodytwo");
2789
2790 let mut root = Node::Root(Root {
2791 position: None,
2792 children: vec![
2793 heading(1, "one"),
2794 text("body"),
2795 heading(2, "nested"),
2796 text("nested body"),
2797 heading(1, "two"),
2798 ],
2799 });
2800 assert!(root.replace_heading_section(0, replacement(), true, true));
2801 assert_eq!(root.to_string(), "replacementtwo");
2802 }
2803
2804 #[cfg(feature = "serde")]
2805 #[test]
2806 fn align_kind_serialization_and_visitors() {
2807 use serde::de::Visitor;
2808
2809 assert_eq!(serde_json::to_string(&AlignKind::Left).unwrap(), "\"left\"");
2810 assert_eq!(
2811 serde_json::to_string(&AlignKind::Right).unwrap(),
2812 "\"right\""
2813 );
2814 assert_eq!(
2815 serde_json::to_string(&AlignKind::Center).unwrap(),
2816 "\"center\""
2817 );
2818 assert_eq!(serde_json::to_string(&AlignKind::None).unwrap(), "null");
2819 assert_eq!(
2820 serde_json::from_str::<AlignKind>("\"left\"").unwrap(),
2821 AlignKind::Left
2822 );
2823 assert_eq!(
2824 serde_json::from_str::<AlignKind>("null").unwrap(),
2825 AlignKind::None
2826 );
2827
2828 assert_eq!(
2829 AlignKindVisitor
2830 .visit_bytes::<serde_json::Error>(b"right")
2831 .unwrap(),
2832 AlignKind::Right
2833 );
2834 assert_eq!(
2835 AlignKindVisitor
2836 .visit_bytes::<serde_json::Error>(b"left")
2837 .unwrap(),
2838 AlignKind::Left
2839 );
2840 assert_eq!(
2841 AlignKindVisitor
2842 .visit_bytes::<serde_json::Error>(b"center")
2843 .unwrap(),
2844 AlignKind::Center
2845 );
2846 assert_eq!(
2847 AlignKindVisitor.visit_none::<serde_json::Error>().unwrap(),
2848 AlignKind::None
2849 );
2850 assert_eq!(
2851 AlignKindVisitor.visit_unit::<serde_json::Error>().unwrap(),
2852 AlignKind::None
2853 );
2854 assert!(AlignKindVisitor
2855 .visit_str::<serde_json::Error>("invalid")
2856 .is_err());
2857 assert!(AlignKindVisitor
2858 .visit_bytes::<serde_json::Error>(b"invalid")
2859 .is_err());
2860 }
2861}