Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <opensource@datafuselabs.com>"]
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]

Expand Down
61 changes: 34 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,70 @@
# 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<T>` values
- Slices
- Unix epoch timestamps
A Rust utility crate providing enhanced display formatting for various types.

## Features

- **Display Option**: Enhanced formatting for `Option<T>` values
- **Display Slice**: Customizable display formatting for slice types
- **Display Unix Epoch**: Human-readable formatting for Unix timestamp values
- **Display Option**: Format `Option<T>` values with customizable display
- **Display Result**: Format `Result<T, E>` 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

### Display Option

```rust
use display_more::DisplayOption;
use display_more::DisplayOptionExt;

let value: Option<i32> = Some(42);
println!("Value: {}", value.display());
println!("{}", value.display()); // "42"

let none: Option<i32> = None;
println!("{}", none.display()); // "None"
```

### Display Result

```rust
use display_more::DisplayResultExt;

let ok = Result::<i32, &str>::Ok(42);
println!("{}", ok.display()); // "Ok(42)"

let err = Result::<i32, &str>::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.
61 changes: 50 additions & 11 deletions src/display_option/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@

use std::fmt;

/// Implement `Display` for `Option<T>` if T is `Display`.
/// Wrapper that implements `Display` for `Option<T>` 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<T>);
/// 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<T>,
fmt_fn: fn(&T, &mut fmt::Formatter<'_>) -> fmt::Result,
}

impl<T: fmt::Display> fmt::Display for DisplayOption<'_, T> {
impl<T> 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),
}
}
}
Expand All @@ -52,7 +53,35 @@ impl<T> DisplayOptionExt<'_, T> for Option<T>
where T: fmt::Display
{
fn display(&self) -> DisplayOption<T> {
DisplayOption(self)
DisplayOption {
inner: self,
fmt_fn: <T as fmt::Display>::fmt,
}
}
}

/// Extension trait to format `Option<T>` 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<T> DisplayDebugOptionExt<'_, T> for Option<T>
where T: fmt::Debug
{
fn display_debug(&self) -> DisplayOption<T> {
DisplayOption {
inner: self,
fmt_fn: <T as fmt::Debug>::fmt,
}
}
}

Expand All @@ -71,4 +100,14 @@ mod tests {
let option = None::<u64>;
assert_eq!(option.display().to_string(), "None");
}

#[test]
fn test_debug_option() {
assert_eq!(Some(1).display_debug().to_string(), "1");
assert_eq!(None::<u64>.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]");
}
}
53 changes: 49 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,67 @@
// 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<T>`, `Result<T, E>`, 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<i32> = None;
//! assert_eq!(none.display().to_string(), "None");
//! ```
//!
//! ## Display Result
//!
//! ```rust
//! use display_more::DisplayResultExt;
//!
//! let ok = Result::<i32, &str>::Ok(42);
//! assert_eq!(ok.display().to_string(), "Ok(42)");
//!
//! let err = Result::<i32, &str>::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;
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;
Expand Down