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 frontmatter;
23pub use frontmatter::Frontmatter;
24
25pub type Stop = (usize, usize);
28
29#[derive(Clone, Copy, Debug, Eq, PartialEq)]
31#[cfg_attr(
32 feature = "serde",
33 derive(serde::Serialize, serde::Deserialize),
34 serde(rename_all = "lowercase")
35)]
36pub enum ReferenceKind {
37 Shortcut,
39 Collapsed,
41 Full,
43}
44
45#[derive(Clone, Copy, Debug, Eq, PartialEq)]
49pub enum AlignKind {
50 Left,
60 Right,
70 Center,
80 None,
90}
91
92#[cfg(feature = "serde")]
94impl serde::ser::Serialize for AlignKind {
95 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
96 where
97 S: serde::ser::Serializer,
98 {
99 match self {
100 AlignKind::Left => serializer.serialize_unit_variant("AlignKind", 0, "left"),
101 AlignKind::Right => serializer.serialize_unit_variant("AlignKind", 1, "right"),
102 AlignKind::Center => serializer.serialize_unit_variant("AlignKind", 2, "center"),
103 AlignKind::None => serializer.serialize_none(),
104 }
105 }
106}
107
108#[cfg(feature = "serde")]
109struct AlignKindVisitor;
110
111#[cfg(feature = "serde")]
112impl serde::de::Visitor<'_> for AlignKindVisitor {
113 type Value = AlignKind;
114
115 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
116 formatter.write_str("'left', 'right', 'center' or null")
117 }
118
119 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
120 where
121 E: serde::de::Error,
122 {
123 match v {
124 "left" => Ok(AlignKind::Left),
125 "right" => Ok(AlignKind::Right),
126 "center" => Ok(AlignKind::Center),
127 &_ => Err(serde::de::Error::invalid_type(
128 serde::de::Unexpected::Str(v),
129 &self,
130 )),
131 }
132 }
133
134 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
135 where
136 E: serde::de::Error,
137 {
138 match v {
139 b"left" => Ok(AlignKind::Left),
140 b"right" => Ok(AlignKind::Right),
141 b"center" => Ok(AlignKind::Center),
142 &_ => Err(serde::de::Error::invalid_type(
143 serde::de::Unexpected::Bytes(v),
144 &self,
145 )),
146 }
147 }
148
149 fn visit_none<E>(self) -> Result<Self::Value, E>
150 where
151 E: serde::de::Error,
152 {
153 Ok(AlignKind::None)
154 }
155
156 fn visit_unit<E>(self) -> Result<Self::Value, E>
157 where
158 E: serde::de::Error,
159 {
160 Ok(AlignKind::None)
161 }
162}
163
164#[cfg(feature = "serde")]
165impl<'de> serde::de::Deserialize<'de> for AlignKind {
166 fn deserialize<D>(deserializer: D) -> Result<AlignKind, D::Error>
167 where
168 D: serde::de::Deserializer<'de>,
169 {
170 deserializer.deserialize_any(AlignKindVisitor)
171 }
172}
173
174#[derive(Clone, Eq, PartialEq)]
176#[cfg_attr(
177 feature = "serde",
178 derive(serde::Serialize, serde::Deserialize),
179 serde(tag = "type", rename_all = "camelCase")
180)]
181pub enum Node {
182 Root(Root),
185
186 Fragment(Fragment),
191 Blockquote(Blockquote),
193 FootnoteDefinition(FootnoteDefinition),
195 MdxJsxFlowElement(MdxJsxFlowElement),
197 List(List),
199
200 Frontmatter(Frontmatter),
203 MdxjsEsm(MdxjsEsm),
205 Toml(Toml),
207 Yaml(Yaml),
209
210 Break(Break),
213 InlineCode(InlineCode),
215 InlineMath(InlineMath),
217 Delete(Delete),
219 Emphasis(Emphasis),
221 MdxTextExpression(MdxTextExpression),
223 FootnoteReference(FootnoteReference),
225 Html(Html),
227 Image(Image),
229 ImageReference(ImageReference),
231 MdxJsxTextElement(MdxJsxTextElement),
233 Link(Link),
235 LinkReference(LinkReference),
237 Strong(Strong),
239 Text(Text),
241
242 Code(Code),
245 Math(Math),
247 MdxFlowExpression(MdxFlowExpression),
249 Heading(Heading),
251 Table(Table),
255 ThematicBreak(ThematicBreak),
257
258 TableRow(TableRow),
261
262 TableCell(TableCell),
265
266 ListItem(ListItem),
269
270 Definition(Definition),
273 Paragraph(Paragraph),
275}
276
277impl fmt::Debug for Node {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
280 match self {
281 Node::Root(x) => x.fmt(f),
282 Node::Fragment(x) => x.fmt(f),
283 Node::Blockquote(x) => x.fmt(f),
284 Node::FootnoteDefinition(x) => x.fmt(f),
285 Node::MdxJsxFlowElement(x) => x.fmt(f),
286 Node::List(x) => x.fmt(f),
287 Node::MdxjsEsm(x) => x.fmt(f),
288 Node::Toml(x) => x.fmt(f),
289 Node::Frontmatter(x) => x.fmt(f),
290 Node::Yaml(x) => x.fmt(f),
291 Node::Break(x) => x.fmt(f),
292 Node::InlineCode(x) => x.fmt(f),
293 Node::InlineMath(x) => x.fmt(f),
294 Node::Delete(x) => x.fmt(f),
295 Node::Emphasis(x) => x.fmt(f),
296 Node::MdxTextExpression(x) => x.fmt(f),
297 Node::FootnoteReference(x) => x.fmt(f),
298 Node::Html(x) => x.fmt(f),
299 Node::Image(x) => x.fmt(f),
300 Node::ImageReference(x) => x.fmt(f),
301 Node::MdxJsxTextElement(x) => x.fmt(f),
302 Node::Link(x) => x.fmt(f),
303 Node::LinkReference(x) => x.fmt(f),
304 Node::Strong(x) => x.fmt(f),
305 Node::Text(x) => x.fmt(f),
306 Node::Code(x) => x.fmt(f),
307 Node::Math(x) => x.fmt(f),
308 Node::MdxFlowExpression(x) => x.fmt(f),
309 Node::Heading(x) => x.fmt(f),
310 Node::Table(x) => x.fmt(f),
311 Node::ThematicBreak(x) => x.fmt(f),
312 Node::TableRow(x) => x.fmt(f),
313 Node::TableCell(x) => x.fmt(f),
314 Node::ListItem(x) => x.fmt(f),
315 Node::Definition(x) => x.fmt(f),
316 Node::Paragraph(x) => x.fmt(f),
317 }
318 }
319}
320
321fn children_to_string(children: &[Node]) -> String {
322 children.iter().map(ToString::to_string).collect()
323}
324
325#[allow(clippy::to_string_trait_impl)]
327impl ToString for Node {
328 fn to_string(&self) -> String {
329 match self {
330 Node::Root(x) => children_to_string(&x.children),
332 Node::Fragment(x) => children_to_string(&x.children),
333 Node::Blockquote(x) => children_to_string(&x.children),
334 Node::FootnoteDefinition(x) => children_to_string(&x.children),
335 Node::MdxJsxFlowElement(x) => children_to_string(&x.children),
336 Node::List(x) => children_to_string(&x.children),
337 Node::Delete(x) => children_to_string(&x.children),
338 Node::Emphasis(x) => children_to_string(&x.children),
339 Node::MdxJsxTextElement(x) => children_to_string(&x.children),
340 Node::Link(x) => children_to_string(&x.children),
341 Node::LinkReference(x) => children_to_string(&x.children),
342 Node::Strong(x) => children_to_string(&x.children),
343 Node::Heading(x) => children_to_string(&x.children),
344 Node::Table(x) => children_to_string(&x.children),
345 Node::TableRow(x) => children_to_string(&x.children),
346 Node::TableCell(x) => children_to_string(&x.children),
347 Node::ListItem(x) => children_to_string(&x.children),
348 Node::Paragraph(x) => children_to_string(&x.children),
349
350 Node::MdxjsEsm(x) => x.value.clone(),
352 Node::Toml(x) => x.value.clone(),
353 Node::Frontmatter(x) => x.value.clone(),
354 Node::Yaml(x) => x.value.clone(),
355 Node::InlineCode(x) => x.value.clone(),
356 Node::InlineMath(x) => x.value.clone(),
357 Node::MdxTextExpression(x) => x.value.clone(),
358 Node::Html(x) => x.value.clone(),
359 Node::Text(x) => x.value.clone(),
360 Node::Code(x) => x.value.clone(),
361 Node::Math(x) => x.value.clone(),
362 Node::MdxFlowExpression(x) => x.value.clone(),
363
364 Node::Break(_)
366 | Node::FootnoteReference(_)
367 | Node::Image(_)
368 | Node::ImageReference(_)
369 | Node::ThematicBreak(_)
370 | Node::Definition(_) => String::new(),
371 }
372 }
373}
374
375impl Node {
376 #[must_use]
377 pub fn children(&self) -> Option<&Vec<Node>> {
378 match self {
379 Node::Root(x) => Some(&x.children),
381 Node::Fragment(x) => Some(&x.children),
382 Node::Paragraph(x) => Some(&x.children),
383 Node::Heading(x) => Some(&x.children),
384 Node::Blockquote(x) => Some(&x.children),
385 Node::List(x) => Some(&x.children),
386 Node::ListItem(x) => Some(&x.children),
387 Node::Emphasis(x) => Some(&x.children),
388 Node::Strong(x) => Some(&x.children),
389 Node::Link(x) => Some(&x.children),
390 Node::LinkReference(x) => Some(&x.children),
391 Node::FootnoteDefinition(x) => Some(&x.children),
392 Node::Table(x) => Some(&x.children),
393 Node::TableRow(x) => Some(&x.children),
394 Node::TableCell(x) => Some(&x.children),
395 Node::Delete(x) => Some(&x.children),
396 Node::MdxJsxFlowElement(x) => Some(&x.children),
397 Node::MdxJsxTextElement(x) => Some(&x.children),
398 _ => None,
400 }
401 }
402
403 pub fn children_mut(&mut self) -> Option<&mut Vec<Node>> {
404 match self {
405 Node::Root(x) => Some(&mut x.children),
407 Node::Fragment(x) => Some(&mut x.children),
408 Node::Paragraph(x) => Some(&mut x.children),
409 Node::Heading(x) => Some(&mut x.children),
410 Node::Blockquote(x) => Some(&mut x.children),
411 Node::List(x) => Some(&mut x.children),
412 Node::ListItem(x) => Some(&mut x.children),
413 Node::Emphasis(x) => Some(&mut x.children),
414 Node::Strong(x) => Some(&mut x.children),
415 Node::Link(x) => Some(&mut x.children),
416 Node::LinkReference(x) => Some(&mut x.children),
417 Node::FootnoteDefinition(x) => Some(&mut x.children),
418 Node::Table(x) => Some(&mut x.children),
419 Node::TableRow(x) => Some(&mut x.children),
420 Node::TableCell(x) => Some(&mut x.children),
421 Node::Delete(x) => Some(&mut x.children),
422 Node::MdxJsxFlowElement(x) => Some(&mut x.children),
423 Node::MdxJsxTextElement(x) => Some(&mut x.children),
424 _ => None,
426 }
427 }
428
429 #[must_use]
430 pub fn position(&self) -> Option<&Position> {
431 match self {
432 Node::Root(x) => x.position.as_ref(),
433 Node::Fragment(_) => None,
434 Node::Blockquote(x) => x.position.as_ref(),
435 Node::FootnoteDefinition(x) => x.position.as_ref(),
436 Node::MdxJsxFlowElement(x) => x.position.as_ref(),
437 Node::List(x) => x.position.as_ref(),
438 Node::MdxjsEsm(x) => x.position.as_ref(),
439 Node::Toml(x) => x.position.as_ref(),
440 Node::Frontmatter(x) => x.position.as_ref(),
441 Node::Yaml(x) => x.position.as_ref(),
442 Node::Break(x) => x.position.as_ref(),
443 Node::InlineCode(x) => x.position.as_ref(),
444 Node::InlineMath(x) => x.position.as_ref(),
445 Node::Delete(x) => x.position.as_ref(),
446 Node::Emphasis(x) => x.position.as_ref(),
447 Node::MdxTextExpression(x) => x.position.as_ref(),
448 Node::FootnoteReference(x) => x.position.as_ref(),
449 Node::Html(x) => x.position.as_ref(),
450 Node::Image(x) => x.position.as_ref(),
451 Node::ImageReference(x) => x.position.as_ref(),
452 Node::MdxJsxTextElement(x) => x.position.as_ref(),
453 Node::Link(x) => x.position.as_ref(),
454 Node::LinkReference(x) => x.position.as_ref(),
455 Node::Strong(x) => x.position.as_ref(),
456 Node::Text(x) => x.position.as_ref(),
457 Node::Code(x) => x.position.as_ref(),
458 Node::Math(x) => x.position.as_ref(),
459 Node::MdxFlowExpression(x) => x.position.as_ref(),
460 Node::Heading(x) => x.position.as_ref(),
461 Node::Table(x) => x.position.as_ref(),
462 Node::ThematicBreak(x) => x.position.as_ref(),
463 Node::TableRow(x) => x.position.as_ref(),
464 Node::TableCell(x) => x.position.as_ref(),
465 Node::ListItem(x) => x.position.as_ref(),
466 Node::Definition(x) => x.position.as_ref(),
467 Node::Paragraph(x) => x.position.as_ref(),
468 }
469 }
470
471 pub fn position_mut(&mut self) -> Option<&mut Position> {
472 match self {
473 Node::Root(x) => x.position.as_mut(),
474 Node::Fragment(_) => None,
475 Node::Blockquote(x) => x.position.as_mut(),
476 Node::FootnoteDefinition(x) => x.position.as_mut(),
477 Node::MdxJsxFlowElement(x) => x.position.as_mut(),
478 Node::List(x) => x.position.as_mut(),
479 Node::MdxjsEsm(x) => x.position.as_mut(),
480 Node::Toml(x) => x.position.as_mut(),
481 Node::Frontmatter(x) => x.position.as_mut(),
482 Node::Yaml(x) => x.position.as_mut(),
483 Node::Break(x) => x.position.as_mut(),
484 Node::InlineCode(x) => x.position.as_mut(),
485 Node::InlineMath(x) => x.position.as_mut(),
486 Node::Delete(x) => x.position.as_mut(),
487 Node::Emphasis(x) => x.position.as_mut(),
488 Node::MdxTextExpression(x) => x.position.as_mut(),
489 Node::FootnoteReference(x) => x.position.as_mut(),
490 Node::Html(x) => x.position.as_mut(),
491 Node::Image(x) => x.position.as_mut(),
492 Node::ImageReference(x) => x.position.as_mut(),
493 Node::MdxJsxTextElement(x) => x.position.as_mut(),
494 Node::Link(x) => x.position.as_mut(),
495 Node::LinkReference(x) => x.position.as_mut(),
496 Node::Strong(x) => x.position.as_mut(),
497 Node::Text(x) => x.position.as_mut(),
498 Node::Code(x) => x.position.as_mut(),
499 Node::Math(x) => x.position.as_mut(),
500 Node::MdxFlowExpression(x) => x.position.as_mut(),
501 Node::Heading(x) => x.position.as_mut(),
502 Node::Table(x) => x.position.as_mut(),
503 Node::ThematicBreak(x) => x.position.as_mut(),
504 Node::TableRow(x) => x.position.as_mut(),
505 Node::TableCell(x) => x.position.as_mut(),
506 Node::ListItem(x) => x.position.as_mut(),
507 Node::Definition(x) => x.position.as_mut(),
508 Node::Paragraph(x) => x.position.as_mut(),
509 }
510 }
511
512 pub fn position_set(&mut self, position: Option<Position>) {
513 match self {
514 Node::Root(x) => x.position = position,
515 Node::Fragment(_) => (),
516 Node::Blockquote(x) => x.position = position,
517 Node::FootnoteDefinition(x) => x.position = position,
518 Node::MdxJsxFlowElement(x) => x.position = position,
519 Node::List(x) => x.position = position,
520 Node::MdxjsEsm(x) => x.position = position,
521 Node::Toml(x) => x.position = position,
522 Node::Frontmatter(x) => x.position = position,
523 Node::Yaml(x) => x.position = position,
524 Node::Break(x) => x.position = position,
525 Node::InlineCode(x) => x.position = position,
526 Node::InlineMath(x) => x.position = position,
527 Node::Delete(x) => x.position = position,
528 Node::Emphasis(x) => x.position = position,
529 Node::MdxTextExpression(x) => x.position = position,
530 Node::FootnoteReference(x) => x.position = position,
531 Node::Html(x) => x.position = position,
532 Node::Image(x) => x.position = position,
533 Node::ImageReference(x) => x.position = position,
534 Node::MdxJsxTextElement(x) => x.position = position,
535 Node::Link(x) => x.position = position,
536 Node::LinkReference(x) => x.position = position,
537 Node::Strong(x) => x.position = position,
538 Node::Text(x) => x.position = position,
539 Node::Code(x) => x.position = position,
540 Node::Math(x) => x.position = position,
541 Node::MdxFlowExpression(x) => x.position = position,
542 Node::Heading(x) => x.position = position,
543 Node::Table(x) => x.position = position,
544 Node::ThematicBreak(x) => x.position = position,
545 Node::TableRow(x) => x.position = position,
546 Node::TableCell(x) => x.position = position,
547 Node::ListItem(x) => x.position = position,
548 Node::Definition(x) => x.position = position,
549 Node::Paragraph(x) => x.position = position,
550 }
551 }
552
553 pub fn walk<'a>(&'a self, mut visitor: impl FnMut(&'a Node)) {
555 fn visit<'a>(node: &'a Node, visitor: &mut impl FnMut(&'a Node)) {
556 visitor(node);
557 if let Some(children) = node.children() {
558 for child in children {
559 visit(child, visitor);
560 }
561 }
562 }
563
564 visit(self, &mut visitor);
565 }
566
567 pub fn walk_mut(&mut self, mut visitor: impl FnMut(&mut Node)) {
569 fn visit(node: &mut Node, visitor: &mut impl FnMut(&mut Node)) {
570 visitor(node);
571 if let Some(children) = node.children_mut() {
572 for child in children {
573 visit(child, visitor);
574 }
575 }
576 }
577
578 visit(self, &mut visitor);
579 }
580
581 #[must_use]
586 pub fn text_content(&self) -> String {
587 match self {
588 Node::Image(node) => node.alt.clone(),
589 Node::ImageReference(node) => node.alt.clone(),
590 Node::Break(_) => "\n".into(),
591 Node::Definition(_) | Node::FootnoteReference(_) | Node::ThematicBreak(_) => {
592 String::new()
593 }
594 _ => {
595 if let Some(children) = self.children() {
596 children.iter().map(Node::text_content).collect()
597 } else {
598 self.to_string()
599 }
600 }
601 }
602 }
603
604 #[must_use]
606 pub fn find_heading(&self, title: &str) -> Option<&Node> {
607 self.children()?
608 .iter()
609 .find(|child| matches!(child, Node::Heading(_)) && child.text_content() == title)
610 }
611
612 #[must_use]
614 pub fn code_language(&self) -> Option<&str> {
615 match self {
616 Node::InlineCode(node) => node.lang.as_deref(),
617 Node::Code(node) => node.lang.as_deref(),
618 Node::Frontmatter(node) => node.language(),
619 _ => None,
620 }
621 }
622
623 #[must_use]
629 pub fn code_info(&self) -> Option<String> {
630 match self {
631 Node::InlineCode(node) => node.lang.clone(),
632 Node::Frontmatter(node) => Some(node.info.clone()),
633 Node::Code(node) => match (&node.lang, &node.meta) {
634 (Some(lang), Some(meta)) => Some(alloc::format!("{lang} {meta}")),
635 (Some(lang), None) => Some(lang.clone()),
636 (None, Some(meta)) => Some(meta.clone()),
637 (None, None) => None,
638 },
639 _ => None,
640 }
641 }
642
643 pub fn extract_children(&mut self) -> Option<Node> {
649 self.children_mut().map(|children| {
650 Node::Fragment(Fragment {
651 children: core::mem::take(children),
652 })
653 })
654 }
655
656 pub fn render_with<R: crate::renderer::Renderer>(&self, renderer: &mut R) -> String {
658 renderer.render(self)
659 }
660
661 #[must_use]
672 pub fn to_markdown(&self) -> String {
673 crate::markdown::to_markdown(self).expect("Markdown serialization failed for this AST node")
674 }
675
676 pub fn to_markdown_with_options(
683 &self,
684 options: &crate::markdown::Options,
685 ) -> Result<String, crate::message::Message> {
686 crate::markdown::to_markdown_with_options(self, options)
687 }
688
689 pub fn replace_heading_section(
697 &mut self,
698 heading_index: usize,
699 replacement: Vec<Node>,
700 replace_heading: bool,
701 remove_subsections: bool,
702 ) -> bool {
703 let Some(children) = self.children_mut() else {
704 return false;
705 };
706 let depth = match children.get(heading_index) {
707 Some(Node::Heading(heading)) => heading.depth,
708 _ => return false,
709 };
710 let end = children
711 .iter()
712 .enumerate()
713 .skip(heading_index + 1)
714 .find_map(|(index, node)| {
715 let Node::Heading(next) = node else {
716 return None;
717 };
718 if !remove_subsections || next.depth <= depth {
719 Some(index)
720 } else {
721 None
722 }
723 })
724 .unwrap_or(children.len());
725 let start = if replace_heading {
726 heading_index
727 } else {
728 heading_index + 1
729 };
730
731 children.splice(start..end, replacement);
732 true
733 }
734}
735
736#[derive(Clone, Debug, Eq, PartialEq)]
738#[cfg_attr(
739 feature = "serde",
740 derive(serde::Serialize, serde::Deserialize),
741 serde(untagged)
742)]
743pub enum AttributeContent {
744 Expression(MdxJsxExpressionAttribute),
751 Property(MdxJsxAttribute),
758}
759#[derive(Clone, Debug, Eq, PartialEq)]
761#[cfg_attr(
762 feature = "serde",
763 derive(serde::Serialize, serde::Deserialize),
764 serde(tag = "type", rename = "mdxJsxAttributeValueExpression")
765)]
766pub struct AttributeValueExpression {
767 pub value: String,
768 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
769 pub stops: Vec<Stop>,
770}
771
772#[derive(Clone, Debug, Eq, PartialEq)]
774#[cfg_attr(
775 feature = "serde",
776 derive(serde::Serialize, serde::Deserialize),
777 serde(untagged)
778)]
779pub enum AttributeValue {
780 Expression(AttributeValueExpression),
787 Literal(String),
794}
795
796#[derive(Clone, Debug, Eq, PartialEq)]
801#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
802pub struct Fragment {
803 pub children: Vec<Node>,
805}
806
807#[derive(Clone, Debug, Eq, PartialEq)]
814#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
815pub struct Root {
816 pub children: Vec<Node>,
819 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
821 pub position: Option<Position>,
822}
823
824#[derive(Clone, Debug, Eq, PartialEq)]
831#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
832pub struct Paragraph {
833 pub children: Vec<Node>,
836 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
838 pub position: Option<Position>,
839}
840
841#[derive(Clone, Debug, Eq, PartialEq)]
848#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
849pub struct Heading {
850 pub children: Vec<Node>,
853 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
855 pub position: Option<Position>,
856 pub depth: u8,
859}
860
861#[derive(Clone, Debug, Eq, PartialEq)]
868#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
869pub struct ThematicBreak {
870 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
873 pub position: Option<Position>,
874}
875
876#[derive(Clone, Debug, Eq, PartialEq)]
883#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
884pub struct Blockquote {
885 pub children: Vec<Node>,
888 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
890 pub position: Option<Position>,
891}
892
893#[derive(Clone, Debug, Eq, PartialEq)]
900#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
901pub struct List {
902 pub children: Vec<Node>,
905 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
907 pub position: Option<Position>,
908 pub ordered: bool,
911 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
914 pub start: Option<u32>,
915 pub spread: bool,
918}
919
920#[derive(Clone, Debug, Eq, PartialEq)]
927#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
928pub struct ListItem {
929 pub children: Vec<Node>,
932 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
934 pub position: Option<Position>,
935 pub spread: bool,
939 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
942 pub checked: Option<bool>,
943}
944
945#[derive(Clone, Debug, Eq, PartialEq)]
952#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
953pub struct Html {
954 pub value: String,
957 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
959 pub position: Option<Position>,
960}
961
962#[derive(Clone, Debug, Eq, PartialEq)]
973#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
974pub struct Code {
975 pub value: String,
978 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
980 pub position: Option<Position>,
981 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
984 pub lang: Option<String>,
985 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
987 pub meta: Option<String>,
988}
989
990#[derive(Clone, Debug, Eq, PartialEq)]
1001#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1002pub struct Math {
1003 pub value: String,
1006 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1008 pub position: Option<Position>,
1009 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1012 pub meta: Option<String>,
1013}
1014
1015#[derive(Clone, Debug, Eq, PartialEq)]
1022#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1023pub struct Definition {
1024 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1027 pub position: Option<Position>,
1028 pub url: String,
1031 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1034 pub title: Option<String>,
1035 pub identifier: String,
1041 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1048 pub label: Option<String>,
1049}
1050
1051#[derive(Clone, Debug, Eq, PartialEq)]
1058#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1059pub struct Text {
1060 pub value: String,
1063 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1065 pub position: Option<Position>,
1066}
1067
1068#[derive(Clone, Debug, Eq, PartialEq)]
1075#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1076pub struct Emphasis {
1077 pub children: Vec<Node>,
1080 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1082 pub position: Option<Position>,
1083}
1084
1085#[derive(Clone, Debug, Eq, PartialEq)]
1092#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1093pub struct Strong {
1094 pub children: Vec<Node>,
1097 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1099 pub position: Option<Position>,
1100}
1101
1102#[derive(Clone, Debug, Eq, PartialEq)]
1109#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1110pub struct InlineCode {
1111 pub value: String,
1114 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1116 pub position: Option<Position>,
1117 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1122 pub lang: Option<String>,
1123}
1124
1125#[derive(Clone, Debug, Eq, PartialEq)]
1132#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1133pub struct InlineMath {
1134 pub value: String,
1137 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1139 pub position: Option<Position>,
1140}
1141
1142#[derive(Clone, Debug, Eq, PartialEq)]
1150#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1151pub struct Break {
1152 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1155 pub position: Option<Position>,
1156}
1157
1158#[derive(Clone, Debug, Eq, PartialEq)]
1165#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1166pub struct Link {
1167 pub children: Vec<Node>,
1170 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1172 pub position: Option<Position>,
1173 pub url: String,
1176 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1179 pub title: Option<String>,
1180}
1181
1182#[derive(Clone, Debug, Eq, PartialEq)]
1189#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1190pub struct Image {
1191 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1194 pub position: Option<Position>,
1195 pub alt: String,
1199 pub url: String,
1202 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1205 pub title: Option<String>,
1206}
1207
1208#[derive(Clone, Debug, Eq, PartialEq)]
1215#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1216pub struct LinkReference {
1217 pub children: Vec<Node>,
1220 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1222 pub position: Option<Position>,
1223 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))]
1226 pub reference_kind: ReferenceKind,
1227 pub identifier: String,
1233 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1240 pub label: Option<String>,
1241}
1242
1243#[derive(Clone, Debug, Eq, PartialEq)]
1250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1251pub struct ImageReference {
1252 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1255 pub position: Option<Position>,
1256 pub alt: String,
1260 #[cfg_attr(feature = "serde", serde(rename = "referenceType"))]
1263 pub reference_kind: ReferenceKind,
1264 pub identifier: String,
1270 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1277 pub label: Option<String>,
1278}
1279
1280#[derive(Clone, Debug, Eq, PartialEq)]
1287#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1288pub struct FootnoteDefinition {
1289 pub children: Vec<Node>,
1292 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1294 pub position: Option<Position>,
1295 pub identifier: String,
1301 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1308 pub label: Option<String>,
1309}
1310
1311#[derive(Clone, Debug, Eq, PartialEq)]
1318#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1319pub struct FootnoteReference {
1320 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1323 pub position: Option<Position>,
1324 pub identifier: String,
1330 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1337 pub label: Option<String>,
1338}
1339
1340#[derive(Clone, Debug, Eq, PartialEq)]
1349#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1350pub struct Table {
1351 pub children: Vec<Node>,
1354 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1356 pub position: Option<Position>,
1357 pub align: Vec<AlignKind>,
1360}
1361
1362#[derive(Clone, Debug, Eq, PartialEq)]
1369#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1370pub struct TableRow {
1371 pub children: Vec<Node>,
1374 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1376 pub position: Option<Position>,
1377}
1378
1379#[derive(Clone, Debug, Eq, PartialEq)]
1386#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1387pub struct TableCell {
1388 pub children: Vec<Node>,
1391 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1393 pub position: Option<Position>,
1394}
1395
1396#[derive(Clone, Debug, Eq, PartialEq)]
1403#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1404pub struct Delete {
1405 pub children: Vec<Node>,
1408 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1410 pub position: Option<Position>,
1411}
1412
1413#[derive(Clone, Debug, Eq, PartialEq)]
1424#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1425pub struct Yaml {
1426 pub value: String,
1429 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1431 pub position: Option<Position>,
1432}
1433
1434#[derive(Clone, Debug, Eq, PartialEq)]
1445#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1446pub struct Toml {
1447 pub value: String,
1450 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1452 pub position: Option<Position>,
1453}
1454
1455#[derive(Clone, Debug, Eq, PartialEq)]
1462#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1463pub struct MdxjsEsm {
1464 pub value: String,
1467 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1469 pub position: Option<Position>,
1470
1471 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1473 pub stops: Vec<Stop>,
1474}
1475
1476#[derive(Clone, Debug, Eq, PartialEq)]
1483#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1484pub struct MdxFlowExpression {
1485 pub value: String,
1488 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1490 pub position: Option<Position>,
1491
1492 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1494 pub stops: Vec<Stop>,
1495}
1496
1497#[derive(Clone, Debug, Eq, PartialEq)]
1504#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1505pub struct MdxTextExpression {
1506 pub value: String,
1509 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1511 pub position: Option<Position>,
1512
1513 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1515 pub stops: Vec<Stop>,
1516}
1517
1518#[derive(Clone, Debug, Eq, PartialEq)]
1525#[cfg_attr(
1526 feature = "serde",
1527 derive(serde::Serialize, serde::Deserialize),
1528 serde(rename_all = "camelCase")
1529)]
1530pub struct MdxJsxFlowElement {
1531 pub children: Vec<Node>,
1534 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1536 pub position: Option<Position>,
1537 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1542 pub name: Option<String>,
1543 pub attributes: Vec<AttributeContent>,
1545}
1546
1547#[derive(Clone, Debug, Eq, PartialEq)]
1554#[cfg_attr(
1555 feature = "serde",
1556 derive(serde::Serialize, serde::Deserialize),
1557 serde(rename_all = "camelCase")
1558)]
1559pub struct MdxJsxTextElement {
1560 pub children: Vec<Node>,
1563 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1565 pub position: Option<Position>,
1566 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1571 pub name: Option<String>,
1572 pub attributes: Vec<AttributeContent>,
1574}
1575
1576#[derive(Clone, Debug, Eq, PartialEq)]
1583#[cfg_attr(
1584 feature = "serde",
1585 derive(serde::Serialize, serde::Deserialize),
1586 serde(tag = "type", rename = "mdxJsxAttribute")
1587)]
1588pub struct MdxJsxAttribute {
1589 pub name: String,
1594 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1596 pub value: Option<AttributeValue>,
1597}
1598
1599#[derive(Clone, Debug, Eq, PartialEq)]
1606#[cfg_attr(
1607 feature = "serde",
1608 derive(serde::Serialize, serde::Deserialize),
1609 serde(tag = "type", rename = "mdxJsxExpressionAttribute")
1610)]
1611pub struct MdxJsxExpressionAttribute {
1612 pub value: String,
1614 #[cfg_attr(feature = "serde", serde(rename = "_markdownRsStops"))]
1616 pub stops: Vec<Stop>,
1617}
1618
1619#[cfg(test)]
1620mod tests {
1621 use super::*;
1622 use crate::unist::Position;
1623 use alloc::{format, string::ToString, vec};
1624
1625 #[test]
1628 fn text() {
1629 let mut node = Node::Text(Text {
1630 value: "a".into(),
1631 position: None,
1632 });
1633
1634 assert_eq!(
1635 format!("{node:?}"),
1636 "Text { value: \"a\", position: None }",
1637 "should support `Debug`"
1638 );
1639 assert_eq!(node.to_string(), "a", "should support `ToString`");
1640 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1641 assert_eq!(node.children(), None, "should support `children`");
1642 assert_eq!(node.position(), None, "should support `position`");
1643 assert_eq!(node.position_mut(), None, "should support `position`");
1644 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1645 assert_eq!(
1646 format!("{node:?}"),
1647 "Text { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1648 "should support `position_set`"
1649 );
1650 }
1651
1652 #[test]
1653 fn inline_code() {
1654 let mut node = Node::InlineCode(InlineCode {
1655 value: "a".into(),
1656 position: None,
1657 lang: None,
1658 });
1659
1660 assert_eq!(
1661 format!("{node:?}"),
1662 "InlineCode { value: \"a\", position: None, lang: None }",
1663 "should support `Debug`"
1664 );
1665 assert_eq!(node.to_string(), "a", "should support `ToString`");
1666 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1667 assert_eq!(node.children(), None, "should support `children`");
1668 assert_eq!(node.position(), None, "should support `position`");
1669 assert_eq!(node.position_mut(), None, "should support `position`");
1670 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1671 assert_eq!(
1672 format!("{node:?}"),
1673 "InlineCode { value: \"a\", position: Some(1:1-1:2 (0-1)), lang: None }",
1674 "should support `position_set`"
1675 );
1676 }
1677
1678 #[test]
1679 fn code() {
1680 let mut node = Node::Code(Code {
1681 value: "a".into(),
1682 position: None,
1683 lang: None,
1684 meta: None,
1685 });
1686
1687 assert_eq!(
1688 format!("{node:?}"),
1689 "Code { value: \"a\", position: None, lang: None, meta: None }",
1690 "should support `Debug`"
1691 );
1692 assert_eq!(node.to_string(), "a", "should support `ToString`");
1693 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1694 assert_eq!(node.children(), None, "should support `children`");
1695 assert_eq!(node.position(), None, "should support `position`");
1696 assert_eq!(node.position_mut(), None, "should support `position`");
1697 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1698 assert_eq!(
1699 format!("{node:?}"),
1700 "Code { value: \"a\", position: Some(1:1-1:2 (0-1)), lang: None, meta: None }",
1701 "should support `position_set`"
1702 );
1703 }
1704
1705 #[test]
1706 fn inline_math() {
1707 let mut node = Node::InlineMath(InlineMath {
1708 value: "a".into(),
1709 position: None,
1710 });
1711
1712 assert_eq!(
1713 format!("{node:?}"),
1714 "InlineMath { value: \"a\", position: None }",
1715 "should support `Debug`"
1716 );
1717 assert_eq!(node.to_string(), "a", "should support `ToString`");
1718 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1719 assert_eq!(node.children(), None, "should support `children`");
1720 assert_eq!(node.position(), None, "should support `position`");
1721 assert_eq!(node.position_mut(), None, "should support `position`");
1722 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1723 assert_eq!(
1724 format!("{node:?}"),
1725 "InlineMath { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1726 "should support `position_set`"
1727 );
1728 }
1729
1730 #[test]
1731 fn math() {
1732 let mut node = Node::Math(Math {
1733 value: "a".into(),
1734 position: None,
1735 meta: None,
1736 });
1737
1738 assert_eq!(
1739 format!("{node:?}"),
1740 "Math { value: \"a\", position: None, meta: None }",
1741 "should support `Debug`"
1742 );
1743 assert_eq!(node.to_string(), "a", "should support `ToString`");
1744 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1745 assert_eq!(node.children(), None, "should support `children`");
1746 assert_eq!(node.position(), None, "should support `position`");
1747 assert_eq!(node.position_mut(), None, "should support `position`");
1748 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1749 assert_eq!(
1750 format!("{node:?}"),
1751 "Math { value: \"a\", position: Some(1:1-1:2 (0-1)), meta: None }",
1752 "should support `position_set`"
1753 );
1754 }
1755
1756 #[test]
1757 fn html() {
1758 let mut node = Node::Html(Html {
1759 value: "a".into(),
1760 position: None,
1761 });
1762
1763 assert_eq!(
1764 format!("{node:?}"),
1765 "Html { value: \"a\", position: None }",
1766 "should support `Debug`"
1767 );
1768 assert_eq!(node.to_string(), "a", "should support `ToString`");
1769 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1770 assert_eq!(node.children(), None, "should support `children`");
1771 assert_eq!(node.position(), None, "should support `position`");
1772 assert_eq!(node.position_mut(), None, "should support `position`");
1773 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1774 assert_eq!(
1775 format!("{node:?}"),
1776 "Html { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1777 "should support `position_set`"
1778 );
1779 }
1780
1781 #[test]
1782 fn mdx_text_expression() {
1783 let mut node = Node::MdxTextExpression(MdxTextExpression {
1784 value: "a".into(),
1785 stops: vec![],
1786 position: None,
1787 });
1788
1789 assert_eq!(
1790 format!("{node:?}"),
1791 "MdxTextExpression { value: \"a\", position: None, stops: [] }",
1792 "should support `Debug`"
1793 );
1794 assert_eq!(node.to_string(), "a", "should support `ToString`");
1795 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1796 assert_eq!(node.children(), None, "should support `children`");
1797 assert_eq!(node.position(), None, "should support `position`");
1798 assert_eq!(node.position_mut(), None, "should support `position`");
1799 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1800 assert_eq!(
1801 format!("{node:?}"),
1802 "MdxTextExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1803 "should support `position_set`"
1804 );
1805 }
1806
1807 #[test]
1808 fn mdx_flow_expression() {
1809 let mut node = Node::MdxFlowExpression(MdxFlowExpression {
1810 value: "a".into(),
1811 stops: vec![],
1812 position: None,
1813 });
1814
1815 assert_eq!(
1816 format!("{node:?}"),
1817 "MdxFlowExpression { value: \"a\", position: None, stops: [] }",
1818 "should support `Debug`"
1819 );
1820 assert_eq!(node.to_string(), "a", "should support `ToString`");
1821 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1822 assert_eq!(node.children(), None, "should support `children`");
1823 assert_eq!(node.position(), None, "should support `position`");
1824 assert_eq!(node.position_mut(), None, "should support `position`");
1825 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1826 assert_eq!(
1827 format!("{node:?}"),
1828 "MdxFlowExpression { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1829 "should support `position_set`"
1830 );
1831 }
1832
1833 #[test]
1834 fn mdxjs_esm() {
1835 let mut node = Node::MdxjsEsm(MdxjsEsm {
1836 value: "a".into(),
1837 stops: vec![],
1838 position: None,
1839 });
1840
1841 assert_eq!(
1842 format!("{node:?}"),
1843 "MdxjsEsm { value: \"a\", position: None, stops: [] }",
1844 "should support `Debug`"
1845 );
1846 assert_eq!(node.to_string(), "a", "should support `ToString`");
1847 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1848 assert_eq!(node.children(), None, "should support `children`");
1849 assert_eq!(node.position(), None, "should support `position`");
1850 assert_eq!(node.position_mut(), None, "should support `position`");
1851 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1852 assert_eq!(
1853 format!("{node:?}"),
1854 "MdxjsEsm { value: \"a\", position: Some(1:1-1:2 (0-1)), stops: [] }",
1855 "should support `position_set`"
1856 );
1857 }
1858
1859 #[test]
1860 fn toml() {
1861 let mut node = Node::Toml(Toml {
1862 value: "a".into(),
1863 position: None,
1864 });
1865
1866 assert_eq!(
1867 format!("{node:?}"),
1868 "Toml { value: \"a\", position: None }",
1869 "should support `Debug`"
1870 );
1871 assert_eq!(node.to_string(), "a", "should support `ToString`");
1872 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1873 assert_eq!(node.children(), None, "should support `children`");
1874 assert_eq!(node.position(), None, "should support `position`");
1875 assert_eq!(node.position_mut(), None, "should support `position`");
1876 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1877 assert_eq!(
1878 format!("{node:?}"),
1879 "Toml { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1880 "should support `position_set`"
1881 );
1882 }
1883
1884 #[test]
1885 fn yaml() {
1886 let mut node = Node::Yaml(Yaml {
1887 value: "a".into(),
1888 position: None,
1889 });
1890
1891 assert_eq!(
1892 format!("{node:?}"),
1893 "Yaml { value: \"a\", position: None }",
1894 "should support `Debug`"
1895 );
1896 assert_eq!(node.to_string(), "a", "should support `ToString`");
1897 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1898 assert_eq!(node.children(), None, "should support `children`");
1899 assert_eq!(node.position(), None, "should support `position`");
1900 assert_eq!(node.position_mut(), None, "should support `position`");
1901 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1902 assert_eq!(
1903 format!("{node:?}"),
1904 "Yaml { value: \"a\", position: Some(1:1-1:2 (0-1)) }",
1905 "should support `position_set`"
1906 );
1907 }
1908
1909 #[test]
1912 fn break_node() {
1913 let mut node = Node::Break(Break { position: None });
1914
1915 assert_eq!(
1916 format!("{node:?}"),
1917 "Break { position: None }",
1918 "should support `Debug`"
1919 );
1920 assert_eq!(node.to_string(), "", "should support `ToString`");
1921 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1922 assert_eq!(node.children(), None, "should support `children`");
1923 assert_eq!(node.position(), None, "should support `position`");
1924 assert_eq!(node.position_mut(), None, "should support `position`");
1925 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1926 assert_eq!(
1927 format!("{node:?}"),
1928 "Break { position: Some(1:1-1:2 (0-1)) }",
1929 "should support `position_set`"
1930 );
1931 }
1932
1933 #[test]
1934 fn thematic_break() {
1935 let mut node = Node::ThematicBreak(ThematicBreak { position: None });
1936
1937 assert_eq!(
1938 format!("{node:?}"),
1939 "ThematicBreak { position: None }",
1940 "should support `Debug`"
1941 );
1942 assert_eq!(node.to_string(), "", "should support `ToString`");
1943 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1944 assert_eq!(node.children(), None, "should support `children`");
1945 assert_eq!(node.position(), None, "should support `position`");
1946 assert_eq!(node.position_mut(), None, "should support `position`");
1947 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1948 assert_eq!(
1949 format!("{node:?}"),
1950 "ThematicBreak { position: Some(1:1-1:2 (0-1)) }",
1951 "should support `position_set`"
1952 );
1953 }
1954
1955 #[test]
1956 fn footnote_reference() {
1957 let mut node = Node::FootnoteReference(FootnoteReference {
1958 position: None,
1959 identifier: "a".into(),
1960 label: Some("b".into()),
1961 });
1962
1963 assert_eq!(
1964 format!("{node:?}"),
1965 "FootnoteReference { position: None, identifier: \"a\", label: Some(\"b\") }",
1966 "should support `Debug`"
1967 );
1968 assert_eq!(node.to_string(), "", "should support `ToString`");
1969 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1970 assert_eq!(node.children(), None, "should support `children`");
1971 assert_eq!(node.position(), None, "should support `position`");
1972 assert_eq!(node.position_mut(), None, "should support `position`");
1973 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
1974 assert_eq!(
1975 format!("{node:?}"),
1976 "FootnoteReference { position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: Some(\"b\") }",
1977 "should support `position_set`"
1978 );
1979 }
1980
1981 #[test]
1982 fn image_reference() {
1983 let mut node = Node::ImageReference(ImageReference {
1984 position: None,
1985 alt: "a".into(),
1986 identifier: "b".into(),
1987 label: Some("c".into()),
1988 reference_kind: ReferenceKind::Full,
1989 });
1990
1991 assert_eq!(
1992 format!("{node:?}"),
1993 "ImageReference { position: None, alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }",
1994 "should support `Debug`"
1995 );
1996 assert_eq!(node.to_string(), "", "should support `ToString`");
1997 assert_eq!(node.children_mut(), None, "should support `children_mut`");
1998 assert_eq!(node.children(), None, "should support `children`");
1999 assert_eq!(node.position(), None, "should support `position`");
2000 assert_eq!(node.position_mut(), None, "should support `position`");
2001 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2002 assert_eq!(
2003 format!("{node:?}"),
2004 "ImageReference { position: Some(1:1-1:2 (0-1)), alt: \"a\", reference_kind: Full, identifier: \"b\", label: Some(\"c\") }",
2005 "should support `position_set`"
2006 );
2007 }
2008
2009 #[test]
2010 fn image() {
2011 let mut node = Node::Image(Image {
2012 position: None,
2013 alt: "a".into(),
2014 url: "b".into(),
2015 title: None,
2016 });
2017
2018 assert_eq!(
2019 format!("{node:?}"),
2020 "Image { position: None, alt: \"a\", url: \"b\", title: None }",
2021 "should support `Debug`"
2022 );
2023 assert_eq!(node.to_string(), "", "should support `ToString`");
2024 assert_eq!(node.children_mut(), None, "should support `children_mut`");
2025 assert_eq!(node.children(), None, "should support `children`");
2026 assert_eq!(node.position(), None, "should support `position`");
2027 assert_eq!(node.position_mut(), None, "should support `position`");
2028 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2029 assert_eq!(
2030 format!("{node:?}"),
2031 "Image { position: Some(1:1-1:2 (0-1)), alt: \"a\", url: \"b\", title: None }",
2032 "should support `position_set`"
2033 );
2034 }
2035
2036 #[test]
2037 fn definition() {
2038 let mut node = Node::Definition(Definition {
2039 position: None,
2040 identifier: "a".into(),
2041 label: None,
2042 url: "b".into(),
2043 title: None,
2044 });
2045
2046 assert_eq!(
2047 format!("{node:?}"),
2048 "Definition { position: None, url: \"b\", title: None, identifier: \"a\", label: None }",
2049 "should support `Debug`"
2050 );
2051 assert_eq!(node.to_string(), "", "should support `ToString`");
2052 assert_eq!(node.children_mut(), None, "should support `children_mut`");
2053 assert_eq!(node.children(), None, "should support `children`");
2054 assert_eq!(node.position(), None, "should support `position`");
2055 assert_eq!(node.position_mut(), None, "should support `position`");
2056 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2057 assert_eq!(
2058 format!("{node:?}"),
2059 "Definition { position: Some(1:1-1:2 (0-1)), url: \"b\", title: None, identifier: \"a\", label: None }",
2060 "should support `position_set`"
2061 );
2062 }
2063
2064 #[test]
2067 fn root() {
2068 let mut node = Node::Root(Root {
2069 position: None,
2070 children: vec![],
2071 });
2072
2073 assert_eq!(
2074 format!("{node:?}"),
2075 "Root { children: [], position: None }",
2076 "should support `Debug`"
2077 );
2078 assert_eq!(node.to_string(), "", "should support `ToString`");
2079 assert_eq!(
2080 node.children_mut(),
2081 Some(&mut vec![]),
2082 "should support `children_mut`"
2083 );
2084 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2085 assert_eq!(node.position(), None, "should support `position`");
2086 assert_eq!(node.position_mut(), None, "should support `position`");
2087 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2088 assert_eq!(
2089 format!("{node:?}"),
2090 "Root { children: [], position: Some(1:1-1:2 (0-1)) }",
2091 "should support `position_set`"
2092 );
2093 }
2094
2095 #[test]
2096 fn block_quote() {
2097 let mut node = Node::Blockquote(Blockquote {
2098 position: None,
2099 children: vec![],
2100 });
2101
2102 assert_eq!(
2103 format!("{node:?}"),
2104 "Blockquote { children: [], position: None }",
2105 "should support `Debug`"
2106 );
2107 assert_eq!(node.to_string(), "", "should support `ToString`");
2108 assert_eq!(
2109 node.children_mut(),
2110 Some(&mut vec![]),
2111 "should support `children_mut`"
2112 );
2113 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2114 assert_eq!(node.position(), None, "should support `position`");
2115 assert_eq!(node.position_mut(), None, "should support `position`");
2116 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2117 assert_eq!(
2118 format!("{node:?}"),
2119 "Blockquote { children: [], position: Some(1:1-1:2 (0-1)) }",
2120 "should support `position_set`"
2121 );
2122 }
2123
2124 #[test]
2125 fn delete() {
2126 let mut node = Node::Delete(Delete {
2127 position: None,
2128 children: vec![],
2129 });
2130
2131 assert_eq!(
2132 format!("{node:?}"),
2133 "Delete { children: [], position: None }",
2134 "should support `Debug`"
2135 );
2136 assert_eq!(node.to_string(), "", "should support `ToString`");
2137 assert_eq!(
2138 node.children_mut(),
2139 Some(&mut vec![]),
2140 "should support `children_mut`"
2141 );
2142 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2143 assert_eq!(node.position(), None, "should support `position`");
2144 assert_eq!(node.position_mut(), None, "should support `position`");
2145 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2146 assert_eq!(
2147 format!("{node:?}"),
2148 "Delete { children: [], position: Some(1:1-1:2 (0-1)) }",
2149 "should support `position_set`"
2150 );
2151 }
2152
2153 #[test]
2154 fn emphasis() {
2155 let mut node = Node::Emphasis(Emphasis {
2156 position: None,
2157 children: vec![],
2158 });
2159
2160 assert_eq!(
2161 format!("{node:?}"),
2162 "Emphasis { children: [], position: None }",
2163 "should support `Debug`"
2164 );
2165 assert_eq!(node.to_string(), "", "should support `ToString`");
2166 assert_eq!(
2167 node.children_mut(),
2168 Some(&mut vec![]),
2169 "should support `children_mut`"
2170 );
2171 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2172 assert_eq!(node.position(), None, "should support `position`");
2173 assert_eq!(node.position_mut(), None, "should support `position`");
2174 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2175 assert_eq!(
2176 format!("{node:?}"),
2177 "Emphasis { children: [], position: Some(1:1-1:2 (0-1)) }",
2178 "should support `position_set`"
2179 );
2180 }
2181
2182 #[test]
2183 fn strong() {
2184 let mut node = Node::Strong(Strong {
2185 position: None,
2186 children: vec![],
2187 });
2188
2189 assert_eq!(
2190 format!("{node:?}"),
2191 "Strong { children: [], position: None }",
2192 "should support `Debug`"
2193 );
2194 assert_eq!(node.to_string(), "", "should support `ToString`");
2195 assert_eq!(
2196 node.children_mut(),
2197 Some(&mut vec![]),
2198 "should support `children_mut`"
2199 );
2200 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2201 assert_eq!(node.position(), None, "should support `position`");
2202 assert_eq!(node.position_mut(), None, "should support `position`");
2203 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2204 assert_eq!(
2205 format!("{node:?}"),
2206 "Strong { children: [], position: Some(1:1-1:2 (0-1)) }",
2207 "should support `position_set`"
2208 );
2209 }
2210
2211 #[test]
2212 fn paragraph() {
2213 let mut node = Node::Paragraph(Paragraph {
2214 position: None,
2215 children: vec![],
2216 });
2217
2218 assert_eq!(
2219 format!("{node:?}"),
2220 "Paragraph { children: [], position: None }",
2221 "should support `Debug`"
2222 );
2223 assert_eq!(node.to_string(), "", "should support `ToString`");
2224 assert_eq!(
2225 node.children_mut(),
2226 Some(&mut vec![]),
2227 "should support `children_mut`"
2228 );
2229 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2230 assert_eq!(node.position(), None, "should support `position`");
2231 assert_eq!(node.position_mut(), None, "should support `position`");
2232 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2233 assert_eq!(
2234 format!("{node:?}"),
2235 "Paragraph { children: [], position: Some(1:1-1:2 (0-1)) }",
2236 "should support `position_set`"
2237 );
2238 }
2239
2240 #[test]
2241 fn table_row() {
2242 let mut node = Node::TableRow(TableRow {
2243 position: None,
2244 children: vec![],
2245 });
2246
2247 assert_eq!(
2248 format!("{node:?}"),
2249 "TableRow { children: [], position: None }",
2250 "should support `Debug`"
2251 );
2252 assert_eq!(node.to_string(), "", "should support `ToString`");
2253 assert_eq!(
2254 node.children_mut(),
2255 Some(&mut vec![]),
2256 "should support `children_mut`"
2257 );
2258 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2259 assert_eq!(node.position(), None, "should support `position`");
2260 assert_eq!(node.position_mut(), None, "should support `position`");
2261 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2262 assert_eq!(
2263 format!("{node:?}"),
2264 "TableRow { children: [], position: Some(1:1-1:2 (0-1)) }",
2265 "should support `position_set`"
2266 );
2267 }
2268
2269 #[test]
2270 fn table_cell() {
2271 let mut node = Node::TableCell(TableCell {
2272 position: None,
2273 children: vec![],
2274 });
2275
2276 assert_eq!(
2277 format!("{node:?}"),
2278 "TableCell { children: [], position: None }",
2279 "should support `Debug`"
2280 );
2281 assert_eq!(node.to_string(), "", "should support `ToString`");
2282 assert_eq!(
2283 node.children_mut(),
2284 Some(&mut vec![]),
2285 "should support `children_mut`"
2286 );
2287 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2288 assert_eq!(node.position(), None, "should support `position`");
2289 assert_eq!(node.position_mut(), None, "should support `position`");
2290 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2291 assert_eq!(
2292 format!("{node:?}"),
2293 "TableCell { children: [], position: Some(1:1-1:2 (0-1)) }",
2294 "should support `position_set`"
2295 );
2296 }
2297
2298 #[test]
2299 fn heading() {
2300 let mut node = Node::Heading(Heading {
2301 position: None,
2302 depth: 1,
2303 children: vec![],
2304 });
2305
2306 assert_eq!(
2307 format!("{node:?}"),
2308 "Heading { children: [], position: None, depth: 1 }",
2309 "should support `Debug`"
2310 );
2311 assert_eq!(node.to_string(), "", "should support `ToString`");
2312 assert_eq!(
2313 node.children_mut(),
2314 Some(&mut vec![]),
2315 "should support `children_mut`"
2316 );
2317 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2318 assert_eq!(node.position(), None, "should support `position`");
2319 assert_eq!(node.position_mut(), None, "should support `position`");
2320 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2321 assert_eq!(
2322 format!("{node:?}"),
2323 "Heading { children: [], position: Some(1:1-1:2 (0-1)), depth: 1 }",
2324 "should support `position_set`"
2325 );
2326 }
2327
2328 #[test]
2329 fn table() {
2330 let mut node = Node::Table(Table {
2331 position: None,
2332 align: vec![],
2333 children: vec![],
2334 });
2335
2336 assert_eq!(
2337 format!("{node:?}"),
2338 "Table { children: [], position: None, align: [] }",
2339 "should support `Debug`"
2340 );
2341 assert_eq!(node.to_string(), "", "should support `ToString`");
2342 assert_eq!(
2343 node.children_mut(),
2344 Some(&mut vec![]),
2345 "should support `children_mut`"
2346 );
2347 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2348 assert_eq!(node.position(), None, "should support `position`");
2349 assert_eq!(node.position_mut(), None, "should support `position`");
2350 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2351 assert_eq!(
2352 format!("{node:?}"),
2353 "Table { children: [], position: Some(1:1-1:2 (0-1)), align: [] }",
2354 "should support `position_set`"
2355 );
2356 }
2357
2358 #[test]
2359 fn list_item() {
2360 let mut node = Node::ListItem(ListItem {
2361 position: None,
2362 spread: false,
2363 checked: None,
2364 children: vec![],
2365 });
2366
2367 assert_eq!(
2368 format!("{node:?}"),
2369 "ListItem { children: [], position: None, spread: false, checked: None }",
2370 "should support `Debug`"
2371 );
2372 assert_eq!(node.to_string(), "", "should support `ToString`");
2373 assert_eq!(
2374 node.children_mut(),
2375 Some(&mut vec![]),
2376 "should support `children_mut`"
2377 );
2378 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2379 assert_eq!(node.position(), None, "should support `position`");
2380 assert_eq!(node.position_mut(), None, "should support `position`");
2381 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2382 assert_eq!(
2383 format!("{node:?}"),
2384 "ListItem { children: [], position: Some(1:1-1:2 (0-1)), spread: false, checked: None }",
2385 "should support `position_set`"
2386 );
2387 }
2388
2389 #[test]
2390 fn list() {
2391 let mut node = Node::List(List {
2392 position: None,
2393 spread: false,
2394 ordered: false,
2395 start: None,
2396 children: vec![],
2397 });
2398
2399 assert_eq!(
2400 format!("{node:?}"),
2401 "List { children: [], position: None, ordered: false, start: None, spread: false }",
2402 "should support `Debug`"
2403 );
2404 assert_eq!(node.to_string(), "", "should support `ToString`");
2405 assert_eq!(
2406 node.children_mut(),
2407 Some(&mut vec![]),
2408 "should support `children_mut`"
2409 );
2410 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2411 assert_eq!(node.position(), None, "should support `position`");
2412 assert_eq!(node.position_mut(), None, "should support `position`");
2413 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2414 assert_eq!(
2415 format!("{node:?}"),
2416 "List { children: [], position: Some(1:1-1:2 (0-1)), ordered: false, start: None, spread: false }",
2417 "should support `position_set`"
2418 );
2419 }
2420
2421 #[test]
2422 fn link_reference() {
2423 let mut node = Node::LinkReference(LinkReference {
2424 position: None,
2425 identifier: "a".into(),
2426 label: None,
2427 reference_kind: ReferenceKind::Full,
2428 children: vec![],
2429 });
2430
2431 assert_eq!(
2432 format!("{node:?}"),
2433 "LinkReference { children: [], position: None, reference_kind: Full, identifier: \"a\", label: None }",
2434 "should support `Debug`"
2435 );
2436 assert_eq!(node.to_string(), "", "should support `ToString`");
2437 assert_eq!(
2438 node.children_mut(),
2439 Some(&mut vec![]),
2440 "should support `children_mut`"
2441 );
2442 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2443 assert_eq!(node.position(), None, "should support `position`");
2444 assert_eq!(node.position_mut(), None, "should support `position`");
2445 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2446 assert_eq!(
2447 format!("{node:?}"),
2448 "LinkReference { children: [], position: Some(1:1-1:2 (0-1)), reference_kind: Full, identifier: \"a\", label: None }",
2449 "should support `position_set`"
2450 );
2451 }
2452
2453 #[test]
2454 fn link() {
2455 let mut node = Node::Link(Link {
2456 position: None,
2457 url: "a".into(),
2458 title: None,
2459 children: vec![],
2460 });
2461
2462 assert_eq!(
2463 format!("{node:?}"),
2464 "Link { children: [], position: None, url: \"a\", title: None }",
2465 "should support `Debug`"
2466 );
2467 assert_eq!(node.to_string(), "", "should support `ToString`");
2468 assert_eq!(
2469 node.children_mut(),
2470 Some(&mut vec![]),
2471 "should support `children_mut`"
2472 );
2473 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2474 assert_eq!(node.position(), None, "should support `position`");
2475 assert_eq!(node.position_mut(), None, "should support `position`");
2476 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2477 assert_eq!(
2478 format!("{node:?}"),
2479 "Link { children: [], position: Some(1:1-1:2 (0-1)), url: \"a\", title: None }",
2480 "should support `position_set`"
2481 );
2482 }
2483
2484 #[test]
2485 fn footnote_definition() {
2486 let mut node = Node::FootnoteDefinition(FootnoteDefinition {
2487 position: None,
2488 identifier: "a".into(),
2489 label: None,
2490 children: vec![],
2491 });
2492
2493 assert_eq!(
2494 format!("{node:?}"),
2495 "FootnoteDefinition { children: [], position: None, identifier: \"a\", label: None }",
2496 "should support `Debug`"
2497 );
2498 assert_eq!(node.to_string(), "", "should support `ToString`");
2499 assert_eq!(
2500 node.children_mut(),
2501 Some(&mut vec![]),
2502 "should support `children_mut`"
2503 );
2504 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2505 assert_eq!(node.position(), None, "should support `position`");
2506 assert_eq!(node.position_mut(), None, "should support `position`");
2507 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2508 assert_eq!(
2509 format!("{node:?}"),
2510 "FootnoteDefinition { children: [], position: Some(1:1-1:2 (0-1)), identifier: \"a\", label: None }",
2511 "should support `position_set`"
2512 );
2513 }
2514
2515 #[test]
2516 fn mdx_jsx_flow_element() {
2517 let mut node = Node::MdxJsxFlowElement(MdxJsxFlowElement {
2518 position: None,
2519 name: None,
2520 attributes: vec![],
2521 children: vec![],
2522 });
2523
2524 assert_eq!(
2525 format!("{node:?}"),
2526 "MdxJsxFlowElement { children: [], position: None, name: None, attributes: [] }",
2527 "should support `Debug`"
2528 );
2529 assert_eq!(node.to_string(), "", "should support `ToString`");
2530 assert_eq!(
2531 node.children_mut(),
2532 Some(&mut vec![]),
2533 "should support `children_mut`"
2534 );
2535 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2536 assert_eq!(node.position(), None, "should support `position`");
2537 assert_eq!(node.position_mut(), None, "should support `position`");
2538 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2539 assert_eq!(
2540 format!("{node:?}"),
2541 "MdxJsxFlowElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }",
2542 "should support `position_set`"
2543 );
2544 }
2545
2546 #[test]
2547 fn mdx_jsx_text_element() {
2548 let mut node = Node::MdxJsxTextElement(MdxJsxTextElement {
2549 position: None,
2550 name: None,
2551 attributes: vec![],
2552 children: vec![],
2553 });
2554
2555 assert_eq!(
2556 format!("{node:?}"),
2557 "MdxJsxTextElement { children: [], position: None, name: None, attributes: [] }",
2558 "should support `Debug`"
2559 );
2560 assert_eq!(node.to_string(), "", "should support `ToString`");
2561 assert_eq!(
2562 node.children_mut(),
2563 Some(&mut vec![]),
2564 "should support `children_mut`"
2565 );
2566 assert_eq!(node.children(), Some(&vec![]), "should support `children`");
2567 assert_eq!(node.position(), None, "should support `position`");
2568 assert_eq!(node.position_mut(), None, "should support `position`");
2569 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2570 assert_eq!(
2571 format!("{node:?}"),
2572 "MdxJsxTextElement { children: [], position: Some(1:1-1:2 (0-1)), name: None, attributes: [] }",
2573 "should support `position_set`"
2574 );
2575 }
2576
2577 #[test]
2578 fn fragment_node_methods() {
2579 let text = Node::Text(Text {
2580 value: "fragment".into(),
2581 position: None,
2582 });
2583 let mut node = Node::Fragment(Fragment {
2584 children: vec![text],
2585 });
2586
2587 assert_eq!(
2588 format!("{node:?}"),
2589 "Fragment { children: [Text { value: \"fragment\", position: None }] }"
2590 );
2591 assert_eq!(node.to_string(), "fragment");
2592 assert_eq!(node.children().map(Vec::len), Some(1));
2593 assert_eq!(node.position(), None);
2594 assert_eq!(node.position_mut(), None);
2595 node.position_set(Some(Position::new(1, 1, 0, 1, 2, 1)));
2596 assert_eq!(node.position(), None);
2597
2598 let extracted = node.extract_children().expect("extract fragment children");
2599 assert_eq!(extracted.to_string(), "fragment");
2600 assert_eq!(node.children().unwrap(), &[]);
2601 assert!(node.extract_children().is_some());
2602 }
2603
2604 #[test]
2605 fn walks_and_mutates_nested_children() {
2606 let mut node = Node::Root(Root {
2607 position: None,
2608 children: vec![Node::Paragraph(Paragraph {
2609 position: None,
2610 children: vec![Node::Text(Text {
2611 value: "before".into(),
2612 position: None,
2613 })],
2614 })],
2615 });
2616
2617 let mut visited = Vec::new();
2618 node.walk(|node| visited.push(node.to_string()));
2619 assert_eq!(visited, ["before", "before", "before"]);
2620
2621 node.walk_mut(|node| {
2622 if let Node::Text(text) = node {
2623 text.value.push_str(" after");
2624 }
2625 });
2626 assert_eq!(node.text_content(), "before after");
2627 }
2628
2629 #[test]
2630 fn node_text_and_heading_helpers() {
2631 let image = Node::Image(Image {
2632 position: None,
2633 alt: "image alt".into(),
2634 url: "image.png".into(),
2635 title: None,
2636 });
2637 let image_reference = Node::ImageReference(ImageReference {
2638 position: None,
2639 alt: "reference alt".into(),
2640 reference_kind: ReferenceKind::Full,
2641 identifier: "image".into(),
2642 label: None,
2643 });
2644 let heading = Node::Heading(Heading {
2645 position: None,
2646 depth: 2,
2647 children: vec![Node::Text(Text {
2648 value: "Target".into(),
2649 position: None,
2650 })],
2651 });
2652 let root = Node::Root(Root {
2653 position: None,
2654 children: vec![image.clone(), image_reference.clone(), heading.clone()],
2655 });
2656
2657 assert_eq!(image.text_content(), "image alt");
2658 assert_eq!(image_reference.text_content(), "reference alt");
2659 assert_eq!(Node::Break(Break { position: None }).text_content(), "\n");
2660 assert_eq!(
2661 Node::ThematicBreak(ThematicBreak { position: None }).text_content(),
2662 ""
2663 );
2664 assert_eq!(
2665 Node::Definition(Definition {
2666 position: None,
2667 identifier: "x".into(),
2668 label: None,
2669 url: "x".into(),
2670 title: None
2671 })
2672 .text_content(),
2673 ""
2674 );
2675 assert_eq!(root.find_heading("Target"), Some(&heading));
2676 assert_eq!(root.find_heading("missing"), None);
2677 assert_eq!(image.find_heading("Target"), None);
2678 assert_eq!(
2679 Node::Text(Text {
2680 value: "x".into(),
2681 position: None
2682 })
2683 .code_language(),
2684 None
2685 );
2686 }
2687
2688 #[test]
2689 fn code_accessors_cover_optional_metadata() {
2690 let inline = Node::InlineCode(InlineCode {
2691 value: "code".into(),
2692 position: None,
2693 lang: Some("rust".into()),
2694 });
2695 assert_eq!(inline.code_language(), Some("rust"));
2696 assert_eq!(inline.code_info().as_deref(), Some("rust"));
2697
2698 for (lang, meta, expected) in [
2699 (Some("rust"), Some("ignore"), Some("rust ignore")),
2700 (Some("rust"), None, Some("rust")),
2701 (None, Some("ignore"), Some("ignore")),
2702 (None, None, None),
2703 ] {
2704 let code = Node::Code(Code {
2705 value: "code".into(),
2706 position: None,
2707 lang: lang.map(Into::into),
2708 meta: meta.map(Into::into),
2709 });
2710 assert_eq!(code.code_language(), lang);
2711 assert_eq!(code.code_info().as_deref(), expected);
2712 }
2713
2714 assert_eq!(
2715 Node::Text(Text {
2716 value: "plain".into(),
2717 position: None,
2718 })
2719 .code_info(),
2720 None
2721 );
2722 }
2723
2724 #[test]
2725 fn node_serializes_markdown_with_custom_options() {
2726 let node = Node::Text(Text {
2727 value: "text".into(),
2728 position: None,
2729 });
2730 let options = crate::markdown::Options::default();
2731
2732 assert_eq!(node.to_markdown_with_options(&options).unwrap(), "text\n");
2733 }
2734
2735 #[test]
2736 fn replaces_heading_sections_with_all_options() {
2737 let heading = |depth, title: &str| {
2738 Node::Heading(Heading {
2739 position: None,
2740 depth,
2741 children: vec![Node::Text(Text {
2742 value: title.into(),
2743 position: None,
2744 })],
2745 })
2746 };
2747 let text = |value: &str| {
2748 Node::Text(Text {
2749 value: value.into(),
2750 position: None,
2751 })
2752 };
2753 let replacement = || vec![text("replacement")];
2754
2755 let mut root = Node::Root(Root {
2756 position: None,
2757 children: vec![
2758 heading(1, "one"),
2759 text("body"),
2760 heading(2, "nested"),
2761 text("nested body"),
2762 heading(1, "two"),
2763 ],
2764 });
2765 assert!(!root.replace_heading_section(1, replacement(), true, false));
2766 assert!(!text("not a parent").replace_heading_section(0, replacement(), true, false));
2767 assert!(root.replace_heading_section(0, replacement(), false, true));
2768 assert_eq!(root.to_string(), "onereplacementtwo");
2769
2770 let mut root = Node::Root(Root {
2771 position: None,
2772 children: vec![
2773 heading(1, "one"),
2774 text("body"),
2775 heading(2, "nested"),
2776 text("nested body"),
2777 heading(1, "two"),
2778 ],
2779 });
2780 assert!(root.replace_heading_section(0, replacement(), true, false));
2781 assert_eq!(root.to_string(), "replacementnestednested bodytwo");
2782
2783 let mut root = Node::Root(Root {
2784 position: None,
2785 children: vec![
2786 heading(1, "one"),
2787 text("body"),
2788 heading(2, "nested"),
2789 text("nested body"),
2790 heading(1, "two"),
2791 ],
2792 });
2793 assert!(root.replace_heading_section(0, replacement(), true, true));
2794 assert_eq!(root.to_string(), "replacementtwo");
2795 }
2796
2797 #[cfg(feature = "serde")]
2798 #[test]
2799 fn align_kind_serialization_and_visitors() {
2800 use serde::de::Visitor;
2801
2802 assert_eq!(serde_json::to_string(&AlignKind::Left).unwrap(), "\"left\"");
2803 assert_eq!(
2804 serde_json::to_string(&AlignKind::Right).unwrap(),
2805 "\"right\""
2806 );
2807 assert_eq!(
2808 serde_json::to_string(&AlignKind::Center).unwrap(),
2809 "\"center\""
2810 );
2811 assert_eq!(serde_json::to_string(&AlignKind::None).unwrap(), "null");
2812 assert_eq!(
2813 serde_json::from_str::<AlignKind>("\"left\"").unwrap(),
2814 AlignKind::Left
2815 );
2816 assert_eq!(
2817 serde_json::from_str::<AlignKind>("null").unwrap(),
2818 AlignKind::None
2819 );
2820
2821 assert_eq!(
2822 AlignKindVisitor
2823 .visit_bytes::<serde_json::Error>(b"right")
2824 .unwrap(),
2825 AlignKind::Right
2826 );
2827 assert_eq!(
2828 AlignKindVisitor
2829 .visit_bytes::<serde_json::Error>(b"left")
2830 .unwrap(),
2831 AlignKind::Left
2832 );
2833 assert_eq!(
2834 AlignKindVisitor
2835 .visit_bytes::<serde_json::Error>(b"center")
2836 .unwrap(),
2837 AlignKind::Center
2838 );
2839 assert_eq!(
2840 AlignKindVisitor.visit_none::<serde_json::Error>().unwrap(),
2841 AlignKind::None
2842 );
2843 assert_eq!(
2844 AlignKindVisitor.visit_unit::<serde_json::Error>().unwrap(),
2845 AlignKind::None
2846 );
2847 assert!(AlignKindVisitor
2848 .visit_str::<serde_json::Error>("invalid")
2849 .is_err());
2850 assert!(AlignKindVisitor
2851 .visit_bytes::<serde_json::Error>(b"invalid")
2852 .is_err());
2853 }
2854}