extern crate annotate_snippets; extern crate serde; use self::serde::de::{Deserialize, Deserializer}; use self::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, #[serde(deserialize_with = "deserialize_annotations")] #[serde(default)] pub footer: Vec, #[serde(deserialize_with = "deserialize_slices")] pub slices: Vec, } fn deserialize_slices<'de, D>(deserializer: D) -> Result, 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, D::Error> where D: Deserializer<'de>, { #[derive(Deserialize)] struct Wrapper(#[serde(with = "AnnotationDef")] Annotation); Option::::deserialize(deserializer) .map(|opt_wrapped: Option| opt_wrapped.map(|wrapped: Wrapper| wrapped.0)) } fn deserialize_annotations<'de, D>(deserializer: D) -> Result, 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, #[serde(deserialize_with = "deserialize_source_annotations")] pub annotations: Vec, #[serde(default)] pub fold: bool, } fn deserialize_source_annotations<'de, D>( deserializer: D, ) -> Result, 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, pub label: Option, #[serde(with = "AnnotationTypeDef")] pub annotation_type: AnnotationType, } #[allow(dead_code)] #[derive(Serialize, Deserialize)] #[serde(remote = "AnnotationType")] enum AnnotationTypeDef { Error, Warning, Info, Note, Help, }