From a222dc70de0149aa13091cc94c6e3574773da250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Sch=C3=A4fer?= Date: Fri, 2 May 2025 16:57:08 +0200 Subject: [PATCH] xso: provide nicer error messages on missing trait implementations --- xso/src/lib.rs | 14 ++++++++++++++ xso/src/text.rs | 3 +++ 2 files changed, 17 insertions(+) diff --git a/xso/src/lib.rs b/xso/src/lib.rs index e1c7f03b9c1f9892c9bafcbb0f2c18914d1cf89b..d1caa406ec20309eadc5f6ac2bffac19a5b92f5b 100644 --- a/xso/src/lib.rs +++ b/xso/src/lib.rs @@ -137,6 +137,7 @@ pub use xso_proc::AsXml; /// type is considered a non-breaking change for any given implementation of /// this trait. Always refer to a type's iterator type using fully-qualified /// notation, for example: `::ItemIter`. +#[diagnostic::on_unimplemented(message = "`{Self}` cannot be serialised as XML")] pub trait AsXml { /// The iterator type. /// @@ -234,6 +235,7 @@ pub trait FromEventsBuilder { /// is considered a non-breaking change for any given implementation of this /// trait. Always refer to a type's builder type using fully-qualified /// notation, for example: `::Builder`. +#[diagnostic::on_unimplemented(message = "`{Self}` cannot be parsed from XML")] pub trait FromXml { /// A builder type used to construct the element. /// @@ -266,6 +268,10 @@ pub trait FromXml { /// /// **Important:** See the [`text`][`crate::text`] module's documentation /// for notes regarding implementations for types from third-party crates. +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be parsed from XML text", + note = "If `{Self}` implements `core::fmt::Display` and `core::str::FromStr`, you may be able to provide a suitable implementation using `xso::convert_via_fromstr_and_display!({Self});`." +)] pub trait FromXmlText: Sized { /// Convert the given XML text to a value. fn from_xml_text(data: String) -> Result; @@ -314,6 +320,10 @@ impl FromXmlText for Box { /// /// **Important:** See the [`text`][`crate::text`] module's documentation /// for notes regarding implementations for types from third-party crates. +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be serialised to XML text", + note = "If `{Self}` implements `core::fmt::Display` and `core::str::FromStr`, you may be able to provide a suitable implementation using `xso::convert_via_fromstr_and_display!({Self});`." +)] pub trait AsXmlText { /// Convert the value to an XML string in a context where an absent value /// cannot be represented. @@ -387,6 +397,10 @@ impl AsXmlText for &T { /// /// **Important:** See the [`text`][`crate::text`] module's documentation /// for notes regarding implementations for types from third-party crates. +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be serialised as XML attribute", + note = "If `{Self}` implements `core::fmt::Display` and `core::str::FromStr`, you may be able to provide a suitable implementation using `xso::convert_via_fromstr_and_display!({Self});`." +)] pub trait AsOptionalXmlText { /// Convert the value to an XML string in a context where an absent value /// can be represented. diff --git a/xso/src/text.rs b/xso/src/text.rs index c182842dff4fa5dd9737d23aa8e24d22dd9f384d..3f586d60cec5b374c6b2fdeda909e674a9a35db9 100644 --- a/xso/src/text.rs +++ b/xso/src/text.rs @@ -265,6 +265,9 @@ convert_via_fromstr_and_display! { /// The codec to use for a text can be specified in the attributes understood /// by `FromXml` and `AsXml` derive macros. See the documentation of the /// [`FromXml`][`macro@crate::FromXml`] derive macro for details. +#[diagnostic::on_unimplemented( + message = "`{Self}` cannot be used as XML text codec for values of type `{T}`." +)] pub trait TextCodec { /// Decode a string value into the type. fn decode(&self, s: String) -> Result;