diff --git a/cargo-typify/tests/outputs/attr.rs b/cargo-typify/tests/outputs/attr.rs index f57017f0..9ec11e1e 100644 --- a/cargo-typify/tests/outputs/attr.rs +++ b/cargo-typify/tests/outputs/attr.rs @@ -68,29 +68,3 @@ pub struct Veggies { #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")] pub vegetables: ::std::vec::Vec, } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} diff --git a/cargo-typify/tests/outputs/derive.rs b/cargo-typify/tests/outputs/derive.rs index 6106e88a..e77b9b9b 100644 --- a/cargo-typify/tests/outputs/derive.rs +++ b/cargo-typify/tests/outputs/derive.rs @@ -64,29 +64,3 @@ pub struct Veggies { #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")] pub vegetables: ::std::vec::Vec, } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} diff --git a/cargo-typify/tests/outputs/multi_derive.rs b/cargo-typify/tests/outputs/multi_derive.rs index 09cc5ed6..d818e398 100644 --- a/cargo-typify/tests/outputs/multi_derive.rs +++ b/cargo-typify/tests/outputs/multi_derive.rs @@ -78,29 +78,3 @@ pub struct Veggies { #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")] pub vegetables: ::std::vec::Vec, } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} diff --git a/cargo-typify/tests/outputs/no-builder.rs b/cargo-typify/tests/outputs/no-builder.rs index c98c84b9..2e1fe68a 100644 --- a/cargo-typify/tests/outputs/no-builder.rs +++ b/cargo-typify/tests/outputs/no-builder.rs @@ -64,29 +64,3 @@ pub struct Veggies { #[serde(default, skip_serializing_if = "::std::vec::Vec::is_empty")] pub vegetables: ::std::vec::Vec, } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} diff --git a/typify-impl/src/convert.rs b/typify-impl/src/convert.rs index 8eecb994..7c1716e7 100644 --- a/typify-impl/src/convert.rs +++ b/typify-impl/src/convert.rs @@ -2299,7 +2299,7 @@ mod tests { let actual = type_space.to_stream(); let file = syn::parse2::(actual).expect("type space should emit a valid file"); match file.items.as_slice() { - [syn::Item::Mod(error)] if error.ident == "error" => {} + [] => {} _ => panic!("unexpected file contents {}", file.to_token_stream()), } } diff --git a/typify-impl/src/lib.rs b/typify-impl/src/lib.rs index 4785c7b1..462e30e2 100644 --- a/typify-impl/src/lib.rs +++ b/typify-impl/src/lib.rs @@ -902,8 +902,28 @@ impl TypeSpace { pub fn to_stream(&self) -> TokenStream { let mut output = OutputSpace::default(); - // Add the error type we use for conversions; it's fine if this is - // unused. + // Add all types. + self.id_to_entry + .values() + .for_each(|type_entry| type_entry.output(self, &mut output)); + + // Add all shared default functions. + self.defaults + .iter() + .for_each(|x| output.add_item(output::OutputSpaceMod::Defaults, "", x.into())); + + // Add the error type conversions use, but only when some emitted item + // references it. This is kind of gross that we're groveling around + // through output to decide, but it will--I hope--be short-lived. + if output.contains("ConversionError") { + self.add_error_item(&mut output); + } + + output.into_stream() + } + + /// The error type generated `TryFrom` and `FromStr` impls report. + fn add_error_item(&self, output: &mut OutputSpace) { output.add_item( output::OutputSpaceMod::Error, "", @@ -939,18 +959,6 @@ impl TypeSpace { } }, ); - - // Add all types. - self.id_to_entry - .values() - .for_each(|type_entry| type_entry.output(self, &mut output)); - - // Add all shared default functions. - self.defaults - .iter() - .for_each(|x| output.add_item(output::OutputSpaceMod::Defaults, "", x.into())); - - output.into_stream() } /// Allocated the next TypeId. diff --git a/typify-impl/src/output.rs b/typify-impl/src/output.rs index d33406a3..7220cbb8 100644 --- a/typify-impl/src/output.rs +++ b/typify-impl/src/output.rs @@ -31,6 +31,13 @@ impl OutputSpace { .extend(stream); } + /// Whether any accumulated item's tokens contain `needle`. + pub fn contains(&self, needle: &str) -> bool { + self.items + .values() + .any(|stream| stream.to_string().contains(needle)) + } + pub fn into_stream(self) -> TokenStream { let mods = self .items diff --git a/typify/tests/schemas/arrays-and-tuples.rs b/typify/tests/schemas/arrays-and-tuples.rs index c8ffe924..c71da4cd 100644 --- a/typify/tests/schemas/arrays-and-tuples.rs +++ b/typify/tests/schemas/arrays-and-tuples.rs @@ -139,30 +139,4 @@ impl ::std::convert::From<[::serde_json::Value; 2usize]> for YoloTwoArray { Self(value) } } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} fn main() {} diff --git a/typify/tests/schemas/maps.rs b/typify/tests/schemas/maps.rs index 5388bbe8..a46ef2a8 100644 --- a/typify/tests/schemas/maps.rs +++ b/typify/tests/schemas/maps.rs @@ -181,30 +181,4 @@ impl ::std::str::FromStr for Value { Ok(Self(value.to_string())) } } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} fn main() {} diff --git a/typify/tests/schemas/maps_custom.rs b/typify/tests/schemas/maps_custom.rs index 8843c9a2..407603e1 100644 --- a/typify/tests/schemas/maps_custom.rs +++ b/typify/tests/schemas/maps_custom.rs @@ -181,30 +181,4 @@ impl ::std::str::FromStr for Value { Ok(Self(value.to_string())) } } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} fn main() {} diff --git a/typify/tests/schemas/multiple-instance-types.rs b/typify/tests/schemas/multiple-instance-types.rs index 6f8d9c89..e3e17392 100644 --- a/typify/tests/schemas/multiple-instance-types.rs +++ b/typify/tests/schemas/multiple-instance-types.rs @@ -107,30 +107,4 @@ impl ::std::convert::From for YesNoMaybe { Self::Boolean(value) } } -#[doc = " Error types."] -pub mod error { - #[doc = r" Error from a `TryFrom` or `FromStr` implementation."] - pub struct ConversionError(::std::borrow::Cow<'static, str>); - impl ::std::error::Error for ConversionError {} - impl ::std::fmt::Display for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Display::fmt(&self.0, f) - } - } - impl ::std::fmt::Debug for ConversionError { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> Result<(), ::std::fmt::Error> { - ::std::fmt::Debug::fmt(&self.0, f) - } - } - impl From<&'static str> for ConversionError { - fn from(value: &'static str) -> Self { - Self(value.into()) - } - } - impl From for ConversionError { - fn from(value: String) -> Self { - Self(value.into()) - } - } -} fn main() {}