format-attr 0.2.1

a custom derive to implement Debug/Display easy
Documentation
# 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

| Derive Macro | Priority 1 | Priority 2 (fallback) |
|-------------|------------|----------------------|
| `DisplayAttr` | `#[fmt_display(...)]` | `#[fmt(...)]` |
| `DebugAttr` | `#[fmt_debug(...)]` | `#[fmt(...)]` |

## License

MIT