diff --git a/CHANGELOG.md b/CHANGELOG.md index d56e402..6c7a475 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 0.1.10 (2024-02-12) + +* Add `TypeNameInfo` gated behind `"info"` and `"serde"` features. ([#16]) + +[#16]: https://github.com/azriel91/tynm/pulls/16 + + ## 0.1.9 (2023-09-28) * Add `tynm::type_name*_opts` methods, taking in `TypeParamsFmtOpts` to specify how type parameters are formatted. ([#15]) diff --git a/Cargo.toml b/Cargo.toml index fc7ae7b..b70bb19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tynm" -version = "0.1.9" +version = "0.1.10" authors = ["Azriel Hoh "] edition = "2021" description = "Returns type names in shorter form." @@ -12,12 +12,16 @@ license = "MIT OR Apache-2.0" [dependencies] nom = { version = "7.1.3", default-features = false, features = ["alloc"] } +serde = { version = "1.0.196", optional = true, features = ["derive"] } [dev-dependencies] pretty_assertions = "1.4.0" +serde_yaml = "0.9.31" [features] default = [] +info = [] +serde = ["dep:serde"] [badges] appveyor = { repository = "azriel91/tynm" } diff --git a/README.md b/README.md index d32068c..2b8691b 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,18 @@ Returns type names with a specifiable number of module segments as a `String`. Add the following to `Cargo.toml` ```toml -tynm = "0.1.8" +tynm = "0.1.10" ``` In code: ```rust +#[rustfmt::skip] +assert_eq!( + core::any::type_name::>(), "core::option::Option" +); + +#[rustfmt::skip] let tuples = vec![ (tynm::type_name::>(), "Option"), (tynm::type_namem::>(1), "core::..::Option"), @@ -26,26 +32,24 @@ let tuples = vec![ (tynm::type_namemn::(1, 1), "rust_out::..::three::Struct"), // traits (tynm::type_name::(), "dyn Debug"), - - // core / std - (core::any::type_name::>(), "core::option::Option") ]; tuples .iter() .for_each(|(left, right)| assert_eq!(left, right)); + ``` ## Motivation -The [`std::any::type_name`] function stabilized in Rust 1.38 returns the fully qualified type +The [`core::any::type_name`] function stabilized in Rust 1.38 returns the fully qualified type name with all module segments. This can be difficult to read in error messages, especially for type-parameterized types. Often, the simple type name is more readable, and enough to distinguish the type referenced in an error. -[`std::any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html +[`core::any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html ## License diff --git a/README.tpl b/README.tpl index 8485a25..700ff04 100644 --- a/README.tpl +++ b/README.tpl @@ -1,10 +1,10 @@ +# 🪶 Tynm -- Type Name + [![Crates.io](https://img.shields.io/crates/v/tynm.svg)](https://crates.io/crates/tynm) [![docs.rs](https://img.shields.io/docsrs/tynm)](https://docs.rs/tynm) [![CI](https://github.com/azriel91/tynm/workflows/CI/badge.svg)](https://github.com/azriel91/tynm/actions/workflows/ci.yml) [![Coverage Status](https://codecov.io/gh/azriel91/tynm/branch/main/graph/badge.svg)](https://codecov.io/gh/azriel91/tynm) -# Tynm -- Type Name - {{readme}} ## License diff --git a/src/lib.rs b/src/lib.rs index 4454577..d88ca6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ //! Add the following to `Cargo.toml` //! //! ```toml -//! tynm = "0.1.8" +//! tynm = "0.1.10" //! ``` //! //! In code: @@ -60,10 +60,16 @@ pub use crate::{ types::{TypeName, TypeNameDisplay}, }; +#[cfg(feature = "info")] +pub use crate::type_name_info::TypeNameInfo; + mod parser; mod type_params_fmt_opts; mod types; +#[cfg(feature = "info")] +mod type_name_info; + /// Returns the simple type name. /// /// # Type Parameters diff --git a/src/type_name_info.rs b/src/type_name_info.rs new file mode 100644 index 0000000..01af1ee --- /dev/null +++ b/src/type_name_info.rs @@ -0,0 +1,86 @@ +use alloc::string::String; + +/// Holds both the short and full type names. +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct TypeNameInfo { + /// The short type name, e.g. `"Option"`. + pub short_name: String, + /// The full type name, e.g. `"core::option::Option"`. + pub full_name: String, +} + +impl TypeNameInfo { + /// Returns `TypeNameInfo` for the given `T`. + pub fn new() -> Self { + let short_name = crate::type_name::(); + let full_name = String::from(core::any::type_name::()); + + Self { + short_name, + full_name, + } + } +} + +#[cfg(test)] +mod tests { + use alloc::{format, string::String}; + + use super::TypeNameInfo; + + #[test] + fn clone() { + let type_name_info = TypeNameInfo::new::>(); + + let clone = Clone::clone(&type_name_info); + + assert_eq!(type_name_info, clone); + } + + #[test] + fn debug() { + let type_name_info = TypeNameInfo::new::>(); + + assert_eq!( + "TypeNameInfo { \ + short_name: \"Option\", \ + full_name: \"core::option::Option\" \ + }", + format!("{type_name_info:?}") + ); + } + + #[cfg(feature = "serde")] + #[test] + fn serialize() -> Result<(), serde_yaml::Error> { + let type_name_info = TypeNameInfo::new::>(); + + let serialized = serde_yaml::to_string(&type_name_info)?; + + assert_eq!( + "\ + short_name: Option\n\ + full_name: core::option::Option\n\ + ", + serialized + ); + + Ok(()) + } + + #[cfg(feature = "serde")] + #[test] + fn deserialize() -> Result<(), serde_yaml::Error> { + let deserialized = serde_yaml::from_str( + "\ + short_name: Option\n\ + full_name: core::option::Option\n\ + ", + )?; + + assert_eq!(TypeNameInfo::new::>(), deserialized); + + Ok(()) + } +}