acdc_parser/model/
admonition.rs1use std::fmt::Display;
4use std::str::FromStr;
5
6use serde::{
7 Deserialize, Serialize,
8 ser::{SerializeMap, Serializer},
9};
10
11use crate::{Error, Positioning, SourceLocation};
12
13use super::Block;
14use super::location::{Location, Position};
15use super::metadata::BlockMetadata;
16use super::title::Title;
17
18#[derive(Clone, Debug, PartialEq)]
20#[non_exhaustive]
21pub struct Admonition {
22 pub metadata: BlockMetadata,
23 pub variant: AdmonitionVariant,
24 pub blocks: Vec<Block>,
25 pub title: Title,
26 pub location: Location,
27}
28
29#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
31#[serde(rename_all = "lowercase")]
32pub enum AdmonitionVariant {
33 Note,
34 Tip,
35 Important,
36 Caution,
37 Warning,
38}
39
40impl Display for AdmonitionVariant {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 AdmonitionVariant::Note => write!(f, "note"),
44 AdmonitionVariant::Tip => write!(f, "tip"),
45 AdmonitionVariant::Important => write!(f, "important"),
46 AdmonitionVariant::Caution => write!(f, "caution"),
47 AdmonitionVariant::Warning => write!(f, "warning"),
48 }
49 }
50}
51
52impl FromStr for AdmonitionVariant {
53 type Err = Error;
54
55 fn from_str(variant: &str) -> Result<Self, Self::Err> {
56 match variant.to_lowercase().as_str() {
57 "note" => Ok(AdmonitionVariant::Note),
58 "tip" => Ok(AdmonitionVariant::Tip),
59 "important" => Ok(AdmonitionVariant::Important),
60 "caution" => Ok(AdmonitionVariant::Caution),
61 "warning" => Ok(AdmonitionVariant::Warning),
62 _ => Err(Error::Parse(
63 Box::new(SourceLocation {
64 file: None,
65 positioning: Positioning::Position(Position::default()),
66 }),
67 format!("unknown admonition variant: {variant}"),
68 )),
69 }
70 }
71}
72
73impl Admonition {
74 #[must_use]
76 pub fn new(variant: AdmonitionVariant, blocks: Vec<Block>, location: Location) -> Self {
77 Self {
78 metadata: BlockMetadata::default(),
79 variant,
80 blocks,
81 title: Title::default(),
82 location,
83 }
84 }
85
86 #[must_use]
88 pub fn with_metadata(mut self, metadata: BlockMetadata) -> Self {
89 self.metadata = metadata;
90 self
91 }
92
93 #[must_use]
95 pub fn with_title(mut self, title: Title) -> Self {
96 self.title = title;
97 self
98 }
99}
100
101impl Serialize for Admonition {
102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103 where
104 S: Serializer,
105 {
106 let mut state = serializer.serialize_map(None)?;
107 state.serialize_entry("name", "admonition")?;
108 state.serialize_entry("type", "block")?;
109 state.serialize_entry("variant", &self.variant)?;
110 if !self.metadata.is_default() {
111 state.serialize_entry("metadata", &self.metadata)?;
112 }
113 if !self.title.is_empty() {
114 state.serialize_entry("title", &self.title)?;
115 }
116
117 if !self.blocks.is_empty() {
118 state.serialize_entry("blocks", &self.blocks)?;
119 }
120 state.serialize_entry("location", &self.location)?;
121 state.end()
122 }
123}