1use serde::Deserialize;
4
5use super::openapi_types::OpenApiSpec;
6
7#[derive(Debug, Clone, PartialEq)]
9pub struct ParsedDoc {
10 pub frontmatter: DocFrontmatter,
12 pub content: Vec<DocNode>,
14 pub raw_markdown: String,
16}
17
18#[derive(Debug, Clone, Default, Deserialize, PartialEq)]
20pub struct DocFrontmatter {
21 #[serde(default)]
23 pub title: String,
24 #[serde(default)]
26 pub description: Option<String>,
27 #[serde(rename = "sidebarTitle")]
29 #[serde(default)]
30 pub sidebar_title: Option<String>,
31 #[serde(default)]
33 pub icon: Option<String>,
34}
35
36#[derive(Debug, Clone, PartialEq)]
38pub enum DocNode {
39 Markdown(String),
41 Callout(CalloutNode),
43 Card(CardNode),
45 CardGroup(CardGroupNode),
47 Tabs(TabsNode),
49 Steps(StepsNode),
51 AccordionGroup(AccordionGroupNode),
53 CodeBlock(CodeBlockNode),
55 CodeGroup(CodeGroupNode),
57 ParamField(ParamFieldNode),
59 ResponseField(ResponseFieldNode),
61 Expandable(ExpandableNode),
63 RequestExample(RequestExampleNode),
65 ResponseExample(ResponseExampleNode),
67 Update(UpdateNode),
69 OpenApi(OpenApiNode),
71}
72
73#[derive(Debug, Clone, Copy, PartialEq, Eq)]
75pub enum CalloutType {
76 Tip,
77 Note,
78 Warning,
79 Info,
80}
81
82impl CalloutType {
83 pub fn parse(s: &str) -> Option<Self> {
84 match s.to_lowercase().as_str() {
85 "tip" => Some(Self::Tip),
86 "note" => Some(Self::Note),
87 "warning" => Some(Self::Warning),
88 "info" => Some(Self::Info),
89 _ => None,
90 }
91 }
92
93 pub fn as_str(&self) -> &'static str {
94 match self {
95 Self::Tip => "Tip",
96 Self::Note => "Note",
97 Self::Warning => "Warning",
98 Self::Info => "Info",
99 }
100 }
101
102 pub fn alert_class(&self) -> &'static str {
104 match self {
105 Self::Tip => "alert-success",
106 Self::Note => "alert-info",
107 Self::Warning => "alert-warning",
108 Self::Info => "alert-info",
109 }
110 }
111
112 pub fn icon_name(&self) -> &'static str {
114 match self {
115 Self::Tip => "lightbulb",
116 Self::Note => "info",
117 Self::Warning => "alert-triangle",
118 Self::Info => "info",
119 }
120 }
121}
122
123#[derive(Debug, Clone, PartialEq)]
125pub struct CalloutNode {
126 pub callout_type: CalloutType,
127 pub content: String,
128}
129
130#[derive(Debug, Clone, PartialEq)]
132pub struct CardNode {
133 pub title: String,
134 pub icon: Option<String>,
135 pub href: Option<String>,
136 pub content: String,
137}
138
139#[derive(Debug, Clone, PartialEq)]
141pub struct CardGroupNode {
142 pub cols: u8,
143 pub cards: Vec<CardNode>,
144}
145
146#[derive(Debug, Clone, PartialEq)]
148pub struct TabNode {
149 pub title: String,
150 pub content: Vec<DocNode>,
152}
153
154#[derive(Debug, Clone, PartialEq)]
156pub struct TabsNode {
157 pub tabs: Vec<TabNode>,
158}
159
160#[derive(Debug, Clone, PartialEq)]
162pub struct StepNode {
163 pub title: String,
164 pub content: Vec<DocNode>,
166}
167
168#[derive(Debug, Clone, PartialEq)]
170pub struct StepsNode {
171 pub steps: Vec<StepNode>,
172}
173
174#[derive(Debug, Clone, PartialEq)]
176pub struct AccordionNode {
177 pub title: String,
178 pub icon: Option<String>,
179 pub content: Vec<DocNode>,
181}
182
183#[derive(Debug, Clone, PartialEq)]
185pub struct AccordionGroupNode {
186 pub items: Vec<AccordionNode>,
187}
188
189#[derive(Debug, Clone, PartialEq)]
191pub struct CodeBlockNode {
192 pub language: Option<String>,
193 pub code: String,
194 pub filename: Option<String>,
195}
196
197#[derive(Debug, Clone, PartialEq)]
199pub struct CodeGroupNode {
200 pub blocks: Vec<CodeBlockNode>,
201}
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
205pub enum ParamLocation {
206 Header,
207 Path,
208 Query,
209 Body,
210}
211
212impl ParamLocation {
213 pub fn parse(s: &str) -> Option<Self> {
214 match s.to_lowercase().as_str() {
215 "header" => Some(Self::Header),
216 "path" => Some(Self::Path),
217 "query" => Some(Self::Query),
218 "body" => Some(Self::Body),
219 _ => None,
220 }
221 }
222
223 pub fn as_str(&self) -> &'static str {
224 match self {
225 Self::Header => "header",
226 Self::Path => "path",
227 Self::Query => "query",
228 Self::Body => "body",
229 }
230 }
231
232 pub fn badge_class(&self) -> &'static str {
234 match self {
235 Self::Header => "badge-warning",
236 Self::Path => "badge-primary",
237 Self::Query => "badge-info",
238 Self::Body => "badge-secondary",
239 }
240 }
241}
242
243#[derive(Debug, Clone, PartialEq)]
245pub struct ParamFieldNode {
246 pub name: String,
248 pub location: ParamLocation,
250 pub param_type: String,
252 pub required: bool,
254 pub default: Option<String>,
256 pub content: Vec<DocNode>,
258}
259
260#[derive(Debug, Clone, PartialEq)]
262pub struct ResponseFieldNode {
263 pub name: String,
265 pub field_type: String,
267 pub required: bool,
269 pub content: String,
271 pub expandable: Option<ExpandableNode>,
273}
274
275#[derive(Debug, Clone, PartialEq)]
277pub struct ExpandableNode {
278 pub title: String,
280 pub fields: Vec<ResponseFieldNode>,
282}
283
284#[derive(Debug, Clone, PartialEq)]
286pub struct RequestExampleNode {
287 pub blocks: Vec<CodeBlockNode>,
289}
290
291#[derive(Debug, Clone, PartialEq)]
293pub struct ResponseExampleNode {
294 pub blocks: Vec<CodeBlockNode>,
296}
297
298#[derive(Debug, Clone, PartialEq)]
300pub struct UpdateNode {
301 pub label: String,
303 pub description: String,
305 pub content: Vec<DocNode>,
307}
308
309#[derive(Debug, Clone, PartialEq)]
311pub struct OpenApiNode {
312 pub spec: OpenApiSpec,
314 pub tags: Option<Vec<String>>,
316 pub show_schemas: bool,
318}