1 use serde::{Deserialize, Deserializer, Serialize};
2 
3 use annotate_snippets::{
4     display_list::{FormatOptions, Margin},
5     snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},
6 };
7 
8 #[derive(Deserialize)]
9 pub struct SnippetDef<'a> {
10     #[serde(deserialize_with = "deserialize_annotation")]
11     #[serde(default)]
12     #[serde(borrow)]
13     pub title: Option<Annotation<'a>>,
14     #[serde(deserialize_with = "deserialize_annotations")]
15     #[serde(default)]
16     #[serde(borrow)]
17     pub footer: Vec<Annotation<'a>>,
18     #[serde(deserialize_with = "deserialize_opt")]
19     #[serde(default)]
20     pub opt: FormatOptions,
21     #[serde(deserialize_with = "deserialize_slices")]
22     #[serde(borrow)]
23     pub slices: Vec<Slice<'a>>,
24 }
25 
26 impl<'a> Into<Snippet<'a>> for SnippetDef<'a> {
into(self) -> Snippet<'a>27     fn into(self) -> Snippet<'a> {
28         let SnippetDef {
29             title,
30             footer,
31             opt,
32             slices,
33         } = self;
34         Snippet {
35             title,
36             footer,
37             slices,
38             opt,
39         }
40     }
41 }
42 
deserialize_opt<'de, D>(deserializer: D) -> Result<FormatOptions, D::Error> where D: Deserializer<'de>,43 fn deserialize_opt<'de, D>(deserializer: D) -> Result<FormatOptions, D::Error>
44 where
45     D: Deserializer<'de>,
46 {
47     #[derive(Deserialize)]
48     struct Wrapper(#[serde(with = "FormatOptionsDef")] FormatOptions);
49 
50     Wrapper::deserialize(deserializer).map(|w| w.0)
51 }
52 
53 #[derive(Deserialize)]
54 #[serde(remote = "FormatOptions")]
55 pub struct FormatOptionsDef {
56     #[serde(default)]
57     pub color: bool,
58     #[serde(default)]
59     pub anonymized_line_numbers: bool,
60     #[serde(deserialize_with = "deserialize_margin")]
61     #[serde(default)]
62     pub margin: Option<Margin>,
63 }
64 
deserialize_margin<'de, D>(deserializer: D) -> Result<Option<Margin>, D::Error> where D: Deserializer<'de>,65 fn deserialize_margin<'de, D>(deserializer: D) -> Result<Option<Margin>, D::Error>
66 where
67     D: Deserializer<'de>,
68 {
69     #[derive(Deserialize)]
70     struct Wrapper {
71         whitespace_left: usize,
72         span_left: usize,
73         span_right: usize,
74         label_right: usize,
75         column_width: usize,
76         max_line_len: usize,
77     }
78 
79     Option::<Wrapper>::deserialize(deserializer).map(|opt_wrapped: Option<Wrapper>| {
80         opt_wrapped.map(|wrapped: Wrapper| {
81             let Wrapper {
82                 whitespace_left,
83                 span_left,
84                 span_right,
85                 label_right,
86                 column_width,
87                 max_line_len,
88             } = wrapped;
89             Margin::new(
90                 whitespace_left,
91                 span_left,
92                 span_right,
93                 label_right,
94                 column_width,
95                 max_line_len,
96             )
97         })
98     })
99 }
100 
deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice<'de>>, D::Error> where D: Deserializer<'de>,101 fn deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice<'de>>, D::Error>
102 where
103     D: Deserializer<'de>,
104 {
105     #[derive(Deserialize)]
106     struct Wrapper<'a>(
107         #[serde(with = "SliceDef")]
108         #[serde(borrow)]
109         Slice<'a>,
110     );
111 
112     let v = Vec::deserialize(deserializer)?;
113     Ok(v.into_iter().map(|Wrapper(a)| a).collect())
114 }
115 
deserialize_annotation<'de, D>(deserializer: D) -> Result<Option<Annotation<'de>>, D::Error> where D: Deserializer<'de>,116 fn deserialize_annotation<'de, D>(deserializer: D) -> Result<Option<Annotation<'de>>, D::Error>
117 where
118     D: Deserializer<'de>,
119 {
120     #[derive(Deserialize)]
121     struct Wrapper<'a>(
122         #[serde(with = "AnnotationDef")]
123         #[serde(borrow)]
124         Annotation<'a>,
125     );
126 
127     Option::<Wrapper>::deserialize(deserializer)
128         .map(|opt_wrapped: Option<Wrapper>| opt_wrapped.map(|wrapped: Wrapper| wrapped.0))
129 }
130 
deserialize_annotations<'de, D>(deserializer: D) -> Result<Vec<Annotation<'de>>, D::Error> where D: Deserializer<'de>,131 fn deserialize_annotations<'de, D>(deserializer: D) -> Result<Vec<Annotation<'de>>, D::Error>
132 where
133     D: Deserializer<'de>,
134 {
135     #[derive(Deserialize)]
136     struct Wrapper<'a>(
137         #[serde(with = "AnnotationDef")]
138         #[serde(borrow)]
139         Annotation<'a>,
140     );
141 
142     let v = Vec::deserialize(deserializer)?;
143     Ok(v.into_iter().map(|Wrapper(a)| a).collect())
144 }
145 
146 #[derive(Deserialize)]
147 #[serde(remote = "Slice")]
148 pub struct SliceDef<'a> {
149     #[serde(borrow)]
150     pub source: &'a str,
151     pub line_start: usize,
152     #[serde(borrow)]
153     pub origin: Option<&'a str>,
154     #[serde(deserialize_with = "deserialize_source_annotations")]
155     #[serde(borrow)]
156     pub annotations: Vec<SourceAnnotation<'a>>,
157     #[serde(default)]
158     pub fold: bool,
159 }
160 
deserialize_source_annotations<'de, D>( deserializer: D, ) -> Result<Vec<SourceAnnotation<'de>>, D::Error> where D: Deserializer<'de>,161 fn deserialize_source_annotations<'de, D>(
162     deserializer: D,
163 ) -> Result<Vec<SourceAnnotation<'de>>, D::Error>
164 where
165     D: Deserializer<'de>,
166 {
167     #[derive(Deserialize)]
168     struct Wrapper<'a>(
169         #[serde(with = "SourceAnnotationDef")]
170         #[serde(borrow)]
171         SourceAnnotation<'a>,
172     );
173 
174     let v = Vec::deserialize(deserializer)?;
175     Ok(v.into_iter().map(|Wrapper(a)| a).collect())
176 }
177 
178 #[derive(Serialize, Deserialize)]
179 #[serde(remote = "SourceAnnotation")]
180 pub struct SourceAnnotationDef<'a> {
181     pub range: (usize, usize),
182     #[serde(borrow)]
183     pub label: &'a str,
184     #[serde(with = "AnnotationTypeDef")]
185     pub annotation_type: AnnotationType,
186 }
187 
188 #[derive(Serialize, Deserialize)]
189 #[serde(remote = "Annotation")]
190 pub struct AnnotationDef<'a> {
191     #[serde(borrow)]
192     pub id: Option<&'a str>,
193     #[serde(borrow)]
194     pub label: Option<&'a str>,
195     #[serde(with = "AnnotationTypeDef")]
196     pub annotation_type: AnnotationType,
197 }
198 
199 #[allow(dead_code)]
200 #[derive(Serialize, Deserialize)]
201 #[serde(remote = "AnnotationType")]
202 enum AnnotationTypeDef {
203     Error,
204     Warning,
205     Info,
206     Note,
207     Help,
208 }
209