blob: a08e3fcc34bb7cdc38592f487f0a59ea0a7eb49c [file] [log] [blame]
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,
}