diff --git a/Cargo.toml b/Cargo.toml index 70e364d..f6b2cb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,16 @@ [package] name = "display-more" description = "helper to display various types" -version = "0.2.0" +version = "0.2.1" authors = ["Databend Authors "] license = "Apache-2.0" edition = "2021" +repository = "https://github.com/drmingdrmer/display-more" +homepage = "https://github.com/drmingdrmer/display-more" +documentation = "https://docs.rs/display-more" +readme = "README.md" +keywords = ["display", "formatting", "helper", "option", "slice"] +categories = ["rust-patterns", "value-formatting"] [features] diff --git a/README.md b/README.md index e3ad644..6a07ea9 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,21 @@ # display-more -A Rust utility crate that provides enhanced display formatting for various types. - -## Overview - -`display-more` is a helper library that extends the standard `Display` trait functionality in Rust, providing more flexible and customizable display formatting for common types such as: - -- `Option` values -- Slices -- Unix epoch timestamps +A Rust utility crate providing enhanced display formatting for various types. ## Features -- **Display Option**: Enhanced formatting for `Option` values -- **Display Slice**: Customizable display formatting for slice types -- **Display Unix Epoch**: Human-readable formatting for Unix timestamp values +- **Display Option**: Format `Option` values with customizable display +- **Display Result**: Format `Result` values +- **Display Slice**: Format slices with configurable element limits +- **Display Unix Epoch**: Convert Unix timestamps to human-readable datetime strings ## Usage -Add the following to your `Cargo.toml`: +Add to your `Cargo.toml`: ```toml [dependencies] -display-more = "0.1.0" +display-more = "0.2.0" ``` ## Examples @@ -30,34 +23,48 @@ display-more = "0.1.0" ### Display Option ```rust -use display_more::DisplayOption; +use display_more::DisplayOptionExt; let value: Option = Some(42); -println!("Value: {}", value.display()); +println!("{}", value.display()); // "42" + +let none: Option = None; +println!("{}", none.display()); // "None" +``` + +### Display Result + +```rust +use display_more::DisplayResultExt; + +let ok = Result::::Ok(42); +println!("{}", ok.display()); // "Ok(42)" + +let err = Result::::Err("error"); +println!("{}", err.display()); // "Err(error)" ``` ### Display Slice ```rust -use display_more::DisplaySlice; +use display_more::DisplaySliceExt; -let numbers = [1, 2, 3, 4, 5]; -println!("Numbers: {}", numbers.display()); +let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8]; +println!("{}", numbers.display()); // "[1,2,3,4,..,8]" +println!("{}", numbers.display_n(3)); // "[1,2,..,8]" ``` ### Display Unix Epoch ```rust -use display_more::DisplayUnixEpoch; +use std::time::Duration; +use display_more::DisplayUnixTimeStampExt; -let timestamp = 1671234567; -println!("Time: {}", timestamp.display()); +let timestamp = Duration::from_millis(1723102819023); +println!("{}", timestamp.display_unix_timestamp()); // "2024-08-08T07:40:19.023000Z+0000" +println!("{}", timestamp.display_unix_timestamp_short()); // "2024-08-08T07:40:19.023" ``` ## License -This project is licensed under the Apache License, Version 2.0 - see the [LICENSE](LICENSE) file for details. - -## Contributing - -Contributions are welcome! Please feel free to submit a Pull Request. +Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details. diff --git a/src/display_option/mod.rs b/src/display_option/mod.rs index a890334..294d814 100644 --- a/src/display_option/mod.rs +++ b/src/display_option/mod.rs @@ -14,19 +14,20 @@ use std::fmt; -/// Implement `Display` for `Option` if T is `Display`. +/// Wrapper that implements `Display` for `Option` using either `Display` or `Debug` formatting. /// -/// It outputs a literal string `"None"` if it is None. Otherwise it invokes the Display -/// implementation for T. -pub struct DisplayOption<'a, T: fmt::Display>(pub &'a Option); +/// It outputs a literal string `"None"` if it is None. Otherwise it invokes the stored +/// formatting function for T. +pub struct DisplayOption<'a, T> { + inner: &'a Option, + fmt_fn: fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result, +} -impl fmt::Display for DisplayOption<'_, T> { +impl fmt::Display for DisplayOption<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match &self.0 { - None => { - write!(f, "None") - } - Some(x) => x.fmt(f), + match &self.inner { + None => write!(f, "None"), + Some(x) => (self.fmt_fn)(x, f), } } } @@ -52,7 +53,35 @@ impl DisplayOptionExt<'_, T> for Option where T: fmt::Display { fn display(&self) -> DisplayOption { - DisplayOption(self) + DisplayOption { + inner: self, + fmt_fn: ::fmt, + } + } +} + +/// Extension trait to format `Option` using `Debug` formatting. +/// +/// # Example +/// +/// ```rust +/// use display_more::DisplayDebugOptionExt; +/// +/// let option = Some("hello"); +/// assert_eq!(option.display_debug().to_string(), "\"hello\""); +/// ``` +pub trait DisplayDebugOptionExt<'a, T: fmt::Debug> { + fn display_debug(&'a self) -> DisplayOption<'a, T>; +} + +impl DisplayDebugOptionExt<'_, T> for Option +where T: fmt::Debug +{ + fn display_debug(&self) -> DisplayOption { + DisplayOption { + inner: self, + fmt_fn: ::fmt, + } } } @@ -71,4 +100,14 @@ mod tests { let option = None::; assert_eq!(option.display().to_string(), "None"); } + + #[test] + fn test_debug_option() { + assert_eq!(Some(1).display_debug().to_string(), "1"); + assert_eq!(None::.display_debug().to_string(), "None"); + // Debug adds quotes around strings + assert_eq!(Some("hello").display_debug().to_string(), "\"hello\""); + // Vec has Debug but not Display + assert_eq!(Some(vec![1, 2, 3]).display_debug().to_string(), "[1, 2, 3]"); + } } diff --git a/src/lib.rs b/src/lib.rs index 90c2874..35a67eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,15 +12,59 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Display more types. +//! Enhanced display formatting for various Rust types. //! -//! # Example +//! This crate provides extension traits to add flexible display formatting capabilities +//! for common types including `Option`, `Result`, slices, and Unix timestamps. +//! +//! # Examples +//! +//! ## Display Option //! //! ```rust //! use display_more::DisplayOptionExt; //! -//! let option = Some(1); -//! assert_eq!(option.display().to_string(), "1"); +//! let some = Some(42); +//! assert_eq!(some.display().to_string(), "42"); +//! +//! let none: Option = None; +//! assert_eq!(none.display().to_string(), "None"); +//! ``` +//! +//! ## Display Result +//! +//! ```rust +//! use display_more::DisplayResultExt; +//! +//! let ok = Result::::Ok(42); +//! assert_eq!(ok.display().to_string(), "Ok(42)"); +//! +//! let err = Result::::Err("error"); +//! assert_eq!(err.display().to_string(), "Err(error)"); +//! ``` +//! +//! ## Display Slice +//! +//! ```rust +//! use display_more::DisplaySliceExt; +//! +//! let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8]; +//! assert_eq!(numbers.display().to_string(), "[1,2,3,4,..,8]"); +//! assert_eq!(numbers.display_n(3).to_string(), "[1,2,..,8]"); +//! ``` +//! +//! ## Display Unix Timestamp +//! +//! ```rust +//! use std::time::Duration; +//! +//! use display_more::DisplayUnixTimeStampExt; +//! +//! let timestamp = Duration::from_millis(1723102819023); +//! assert_eq!( +//! timestamp.display_unix_timestamp().to_string(), +//! "2024-08-08T07:40:19.023000Z+0000" +//! ); //! ``` pub mod display_option; @@ -28,6 +72,7 @@ mod display_result; pub mod display_slice; pub mod display_unix_epoch; +pub use display_option::DisplayDebugOptionExt; pub use display_option::DisplayOptionExt; pub use display_result::DisplayResultExt; pub use display_slice::DisplaySliceExt;