diff --git a/Cargo.lock b/Cargo.lock index 8218ad6..bc7c650 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,6 +232,12 @@ dependencies = [ "syn", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.9" @@ -282,6 +288,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "heck" version = "0.4.1" @@ -320,6 +332,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -550,6 +572,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + [[package]] name = "similar" version = "2.5.0" @@ -642,11 +673,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.11" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -865,3 +921,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 5b77b77..d66ef09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,7 +127,7 @@ divan = "0.1.14" glob = "0.3.1" serde = { version = "1.0.199", features = ["derive"] } snapbox = { version = "0.6.0", features = ["diff", "term-svg", "cmd", "examples"] } -toml = "0.5.11" +toml = "0.8.0" tryfn = "0.2.1" [[bench]] diff --git a/tests/fixtures/deserialize.rs b/tests/fixtures/deserialize.rs index a38a88e..4dbf341 100644 --- a/tests/fixtures/deserialize.rs +++ b/tests/fixtures/deserialize.rs @@ -1,36 +1,30 @@ -use serde::{Deserialize, Deserializer, Serialize}; +use serde::Deserialize; use std::ops::Range; use annotate_snippets::renderer::DEFAULT_TERM_WIDTH; use annotate_snippets::{Annotation, Level, Message, Renderer, Snippet}; #[derive(Deserialize)] -pub(crate) struct Fixture<'a> { +pub(crate) struct Fixture { #[serde(default)] pub(crate) renderer: RendererDef, - #[serde(borrow)] - pub(crate) message: MessageDef<'a>, + pub(crate) message: MessageDef, } #[derive(Deserialize)] -pub struct MessageDef<'a> { +pub struct MessageDef { #[serde(with = "LevelDef")] pub level: Level, - #[serde(borrow)] - pub title: &'a str, + pub title: String, #[serde(default)] - #[serde(borrow)] - pub id: Option<&'a str>, + pub id: Option, #[serde(default)] - #[serde(borrow)] - pub footer: Vec>, - #[serde(deserialize_with = "deserialize_snippets")] - #[serde(borrow)] - pub snippets: Vec>, + pub footer: Vec, + pub snippets: Vec, } -impl<'a> From> for Message<'a> { - fn from(val: MessageDef<'a>) -> Self { +impl<'a> From<&'a MessageDef> for Message<'a> { + fn from(val: &'a MessageDef) -> Self { let MessageDef { level, title, @@ -42,43 +36,24 @@ impl<'a> From> for Message<'a> { if let Some(id) = id { message = message.id(id); } - message = message.snippets(snippets); - message = message.footers(footer.into_iter().map(Into::into)); + message = message.snippets(snippets.iter().map(Snippet::from)); + message = message.footers(footer.iter().map(Into::into)); message } } -fn deserialize_snippets<'de, D>(deserializer: D) -> Result>, D::Error> -where - D: Deserializer<'de>, -{ - #[derive(Deserialize)] - struct Wrapper<'a>( - #[serde(with = "SnippetDef")] - #[serde(borrow)] - SnippetDef<'a>, - ); - - let v = Vec::deserialize(deserializer)?; - Ok(v.into_iter().map(|Wrapper(a)| a.into()).collect()) -} - #[derive(Deserialize)] -pub struct SnippetDef<'a> { - #[serde(borrow)] - pub source: &'a str, +pub struct SnippetDef { + pub source: String, pub line_start: usize, - #[serde(borrow)] - pub origin: Option<&'a str>, - #[serde(deserialize_with = "deserialize_annotations")] - #[serde(borrow)] - pub annotations: Vec>, + pub origin: Option, + pub annotations: Vec, #[serde(default)] pub fold: bool, } -impl<'a> From> for Snippet<'a> { - fn from(val: SnippetDef<'a>) -> Self { +impl<'a> From<&'a SnippetDef> for Snippet<'a> { + fn from(val: &'a SnippetDef) -> Self { let SnippetDef { source, line_start, @@ -86,56 +61,36 @@ impl<'a> From> for Snippet<'a> { annotations, fold, } = val; - let mut snippet = Snippet::source(source).line_start(line_start).fold(fold); + let mut snippet = Snippet::source(source).line_start(*line_start).fold(*fold); if let Some(origin) = origin { snippet = snippet.origin(origin); } - snippet = snippet.annotations(annotations); + snippet = snippet.annotations(annotations.iter().map(Into::into)); snippet } } -fn deserialize_annotations<'de, D>(deserializer: D) -> Result>, D::Error> -where - D: Deserializer<'de>, -{ - #[derive(Deserialize)] - struct Wrapper<'a>(#[serde(borrow)] AnnotationDef<'a>); - - let v = Vec::deserialize(deserializer)?; - Ok(v.into_iter().map(|Wrapper(a)| a.into()).collect()) -} - -#[derive(Serialize, Deserialize)] -pub struct AnnotationDef<'a> { +#[derive(Deserialize)] +pub struct AnnotationDef { pub range: Range, - #[serde(borrow)] - pub label: &'a str, + pub label: String, #[serde(with = "LevelDef")] pub level: Level, } -impl<'a> From> for Annotation<'a> { - fn from(val: AnnotationDef<'a>) -> Self { +impl<'a> From<&'a AnnotationDef> for Annotation<'a> { + fn from(val: &'a AnnotationDef) -> Self { let AnnotationDef { range, label, level, } = val; - level.span(range).label(label) + level.span(range.start..range.end).label(label) } } -#[derive(Serialize, Deserialize)] -pub(crate) struct LabelDef<'a> { - #[serde(with = "LevelDef")] - pub(crate) level: Level, - #[serde(borrow)] - pub(crate) label: &'a str, -} - #[allow(dead_code)] -#[derive(Serialize, Deserialize)] +#[derive(Deserialize)] #[serde(remote = "Level")] enum LevelDef { Error, diff --git a/tests/fixtures/main.rs b/tests/fixtures/main.rs index bf37e73..5ff1105 100644 --- a/tests/fixtures/main.rs +++ b/tests/fixtures/main.rs @@ -33,8 +33,10 @@ fn setup(input_path: std::path::PathBuf) -> tryfn::Case { fn test(input_path: &std::path::Path) -> Result> { let src = std::fs::read_to_string(input_path)?; - let (renderer, message): (Renderer, Message<'_>) = - toml::from_str(&src).map(|a: Fixture<'_>| (a.renderer.into(), a.message.into()))?; + let fixture: Fixture = toml::from_str(&src)?; + let renderer: Renderer = fixture.renderer.into(); + let message: Message<'_> = (&fixture.message).into(); + let actual = renderer.render(message).to_string(); Ok(Data::from(actual).coerce_to(DataFormat::TermSvg)) }