| use serde::{Serialize, Deserialize, Deserializer}; |
| |
| use annotate_snippets::snippet::{ |
| Annotation, AnnotationType, Slice, Snippet, SourceAnnotation, |
| }; |
| |
| #[derive(Deserialize)] |
| #[serde(remote = "Snippet")] |
| pub struct SnippetDef { |
| #[serde(deserialize_with = "deserialize_annotation")] |
| #[serde(default)] |
| pub title: Option<Annotation>, |
| #[serde(deserialize_with = "deserialize_annotations")] |
| #[serde(default)] |
| pub footer: Vec<Annotation>, |
| #[serde(deserialize_with = "deserialize_slices")] |
| pub slices: Vec<Slice>, |
| } |
| |
| fn deserialize_slices<'de, D>(deserializer: D) -> Result<Vec<Slice>, D::Error> |
| where |
| D: Deserializer<'de>, |
| { |
| #[derive(Deserialize)] |
| struct Wrapper(#[serde(with = "SliceDef")] Slice); |
| |
| let v = Vec::deserialize(deserializer)?; |
| Ok(v.into_iter().map(|Wrapper(a)| a).collect()) |
| } |
| |
| fn deserialize_annotation<'de, D>(deserializer: D) -> Result<Option<Annotation>, D::Error> |
| where |
| D: Deserializer<'de>, |
| { |
| #[derive(Deserialize)] |
| struct Wrapper(#[serde(with = "AnnotationDef")] Annotation); |
| |
| Option::<Wrapper>::deserialize(deserializer) |
| .map(|opt_wrapped: Option<Wrapper>| opt_wrapped.map(|wrapped: Wrapper| wrapped.0)) |
| } |
| |
| fn deserialize_annotations<'de, D>(deserializer: D) -> Result<Vec<Annotation>, D::Error> |
| where |
| D: Deserializer<'de>, |
| { |
| #[derive(Deserialize)] |
| struct Wrapper(#[serde(with = "AnnotationDef")] Annotation); |
| |
| let v = Vec::deserialize(deserializer)?; |
| Ok(v.into_iter().map(|Wrapper(a)| a).collect()) |
| } |
| |
| #[derive(Deserialize)] |
| #[serde(remote = "Slice")] |
| pub struct SliceDef { |
| pub source: String, |
| pub line_start: usize, |
| pub origin: Option<String>, |
| #[serde(deserialize_with = "deserialize_source_annotations")] |
| pub annotations: Vec<SourceAnnotation>, |
| #[serde(default)] |
| pub fold: bool, |
| } |
| |
| fn deserialize_source_annotations<'de, D>( |
| deserializer: D, |
| ) -> Result<Vec<SourceAnnotation>, D::Error> |
| where |
| D: Deserializer<'de>, |
| { |
| #[derive(Deserialize)] |
| struct Wrapper(#[serde(with = "SourceAnnotationDef")] SourceAnnotation); |
| |
| let v = Vec::deserialize(deserializer)?; |
| Ok(v.into_iter().map(|Wrapper(a)| a).collect()) |
| } |
| |
| #[derive(Serialize, Deserialize)] |
| #[serde(remote = "SourceAnnotation")] |
| pub struct SourceAnnotationDef { |
| pub range: (usize, usize), |
| pub label: String, |
| #[serde(with = "AnnotationTypeDef")] |
| pub annotation_type: AnnotationType, |
| } |
| |
| #[derive(Serialize, Deserialize)] |
| #[serde(remote = "Annotation")] |
| pub struct AnnotationDef { |
| pub id: Option<String>, |
| pub label: Option<String>, |
| #[serde(with = "AnnotationTypeDef")] |
| pub annotation_type: AnnotationType, |
| } |
| |
| #[allow(dead_code)] |
| #[derive(Serialize, Deserialize)] |
| #[serde(remote = "AnnotationType")] |
| enum AnnotationTypeDef { |
| Error, |
| Warning, |
| Info, |
| Note, |
| Help, |
| } |