# format-attr
document: <https://docs.rs/format-attr>
A Rust proc-macro crate that provides custom derive macros for implementing `Display` and `Debug` traits with custom format strings.
## Features
- **`DisplayAttr`** - Derive `std::fmt::Display` with a custom format string
- **`DebugAttr`** - Derive `std::fmt::Debug` with a custom format string
- **`DisplayAsDebug`** - Implement `Display` by delegating to the existing `Debug` implementation
- Support for separate format strings via `#[fmt_display(...)]` and `#[fmt_debug(...)]`
- Fallback to shared `#[fmt(...)]` attribute
## Usage
Add this to your `Cargo.toml`:
```toml
[dependencies]
format-attr = "0"
```
### Basic Example
```rust
use format_attr::{DisplayAttr, DebugAttr};
#[derive(DisplayAttr, DebugAttr)]
#[fmt("Point({}, {})", x, y)] // `self.` prefix is optional for simple field access
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 10, y: 20 };
assert_eq!(format!("{}", p), "Point(10, 20)");
assert_eq!(format!("{:?}", p), "Point(10, 20)");
```
> **Note:** You can omit the `self.` prefix for simple field names. If you need to call methods or use complex expressions, you can still use `self.field.method()` syntax.
### Inline Field Names
You can also use field names directly inside the format string:
```rust
use format_attr::{DisplayAttr, DebugAttr};
#[derive(DisplayAttr, DebugAttr)]
#[fmt("Point({x}, {y})")] // {x} and {y} are automatically replaced with field values
struct Point {
x: i32,
y: i32,
}
let p = Point { x: 10, y: 20 };
assert_eq!(format!("{}", p), "Point(10, 20)");
```
Format specifiers are also supported:
```rust
use format_attr::DisplayAttr;
#[derive(DisplayAttr)]
#[fmt("Name: {name:>10}, Age: {age:?}")]
struct Person {
name: String,
age: u32,
}
let p = Person { name: "Alice".to_string(), age: 30 };
assert_eq!(format!("{}", p), "Name: Alice, Age: 30");
```
### Separate Format Strings
Use `#[fmt_display(...)]` and `#[fmt_debug(...)]` for different output:
```rust
use format_attr::{DisplayAttr, DebugAttr};
#[derive(DisplayAttr, DebugAttr)]
#[fmt_display("User: {}", name)]
#[fmt_debug("User {{ name: {}, age: {} }}", name, age)]
struct User {
name: String,
age: u32,
}
let u = User { name: "Alice".to_string(), age: 30 };
assert_eq!(format!("{}", u), "User: Alice");
assert_eq!(format!("{:?}", u), "User { name: Alice, age: 30 }");
```
### DisplayAsDebug
When you want `Display` to use the same output as `Debug`:
```rust
use format_attr::DisplayAsDebug;
#[derive(Debug, DisplayAsDebug)]
struct Value(i32);
let v = Value(42);
assert_eq!(format!("{}", v), "Value(42)");
assert_eq!(format!("{:?}", v), "Value(42)");
```
## Attribute Priority
| `DisplayAttr` | `#[fmt_display(...)]` | `#[fmt(...)]` |
| `DebugAttr` | `#[fmt_debug(...)]` | `#[fmt(...)]` |
## License
MIT