synonym 0.1.6

Customizable derive macro to create newtypes. It peeks into the underlying type to choose which traits should be implemented.
Documentation
[![Crates.io](https://img.shields.io/crates/v/synonym.svg)](https://crates.io/crates/synonym)
[![Docs.rs](https://docs.rs/synonym/badge.svg)](https://docs.rs/synonym)
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/rust-lang/docs.rs/master/LICENSE)
[![Build Status](https://travis-ci.org/synek317/synonym.svg?branch=master)](https://travis-ci.org/synek317/synonym)
![Maintenance](https://img.shields.io/badge/maintenance-activly--developed-brightgreen.svg)

# Synonym

## Overview

The `synonym` library is a Rust crate designed to simplify the creation of newtypes. It provides a customizable `#[derive(Synonym)]` macro that automatically implements various traits based on the underlying type of your newtype. This saves you from the boilerplate code usually required when defining newtypes.

## Usage

To use `synonym`, add it to your Cargo.toml:

```toml
[dependencies]
synonym = "0.1.5"
```

### Basic example

Import the `Synonym` trait into your Rust file:

```rust
use synonym::Synonym;
```

Then, define your newtype and annotate it with `#[derive(Synonym)]:`
```rust
#[derive(Synonym)]
pub struct MyInt(i32);
```

### Customization with Attributes
You can customize which traits are implemented or skipped using the `#[synonym(skip(...))]` and `#[synonym(force(...))]` attributes:
```rust
#[derive(Synonym)]
#[synonym(skip(Eq, PartialEq))]
pub struct MyString(String);
```

Supported `skip` and `force` values are listed in the *Trait implementation table* below.

## Generated code
When you use `#[derive(Synonym)]`, the library generates implementations for various traits. Here's a simplified example for a newtype `MyInt(i32)`:
```rust
impl Eq for MyInt {}
impl PartialEq for MyInt {
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
}
// ... and so on for other traits
```

## Trait implementation table

Custom methods

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| .as_str()        | String      |               |            |         |     v    |      v     |        v       |    v   |
| .value() [2]     | Value       |      v        |      v     |    v    |     v    |      v     |        v       |    v   |


Conversion

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| AsRef<Inner>     | AsRef       |        v      |      v     |    v    |     v    |      v     |        v       |    v   |
| Borrow<str>      | String      |               |            |         |     v    |      v     |        v       |        |
| From<&'a str>    | String      |               |            |         |     v    |      v [4] |                |        |
| From<String>     | String      |               |            |         |          |      v     |                |        |
| Deref<Inner> [3] | Deref       |               |            |         |          |            |                |        |
| DerefMut     [3] | DerefMut    |               |            |         |          |            |                |        |
| From<Inner>      | From        |        v      |      v     |    v    |     v    |      v     |        v       |    v   |
| FromStr          | FromStr     |        v      |      v     |    v    |     v    |      v     |                |    v   |

Fundamental traits

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| Clone            | Clone       |        v      |      v     |    v    |     v    |      v     |        v       |    v   |
| Copy             | Copy        |        v      |      v     |    v    |                       |        v       |    v   |
| Debug            | Debug       |        v      |      v     |    v    |     v    |      v     |        v       |    v   |
| Default          | Default     |        v      |            |    v    |     v    |      v     |        v       |    v   |
| Display [5]      | Display     |        v      |      v     |    v    |     v    |      v     |        v       |    v   |
| Hash             | Hash        |        v      |      v     |         |     v    |      v     |        v       |    v   |

Comparison

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| PartialOrd       | PartialOrd  |       v       |      v     |    v    |     v    |      v     |        v       |    v   |
| Ord              | Ord         |       v       |      v     |         |     v    |      v     |        v       |    v   |
| PartialEq        | PartialEq   |       v       |      v     |    v    |     v    |      v     |        v       |    v   |
| Eq               | Eq          |       v       |      v     |         |     v    |      v     |        v       |    v   |

Serde [6]

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| Serialize        | Serialize   |       v       |      v     |    v    |     v    |      v     |                |    v   |
| Deserialize      | Deserialize |       v       |      v     |    v    |     v    |      v     |                |    v   |

Maths [7]

|                  | skip/force  | `Integer` [1] | `NonZero*` | `Float` | `String` | `Box<str>` | `&'static str` | `char` |
|------------------|-------------|---------------|------------|---------|----------|------------|----------------|--------|
| Add<Self>=Self   | Number      |       v       |            |    v    |                       |                |        |
| AddAssign<Self>  | Number      |       v       |            |    v    |                       |                |        |
| Sub<Self>=Self   | Number      |       v       |            |    v    |                       |                |        |
| SubAssign<Self>  | Number      |       v       |            |    v    |                       |                |        |
| Mul<Self>=Self   | Number      |       v       |            |    v    |                       |                |        |
| MulAssign<Self>  | Number      |       v       |            |    v    |                       |                |        |
| Div<Self>=Self   | Number      |       v       |            |    v    |                       |                |        |
| DivAssign<Self>  | Number      |       v       |            |    v    |                       |                |        |


[1] Integers are: `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`
[2] .value() returns `Inner` for `Copy` types and `&Inner` for non-`Copy` types
[3] `Deref` and `DerefMut` are never implemented unless they are forced with `#[synonym(force(deref,deref_mut))]`
[4] In constrast to other strings, `FromStr` for `Box<str>` synonyms uses `Inner::From<&'str>` instead of `Inner::FromStr` since there is no `FromStr` implementation for `Box<str>`
[5] Display implementation can be configured, see below
[6] Only provided when feature `with_serde` is enabled
[7] This is subject to change

## Fine-tuning

### Display
To specify how the Display trait should be implemented, you can use the `#[synonym(display = "...")]` attribute. Here are the available options:

* `Opaque`: Formats the output as TypeName(Value).
* `Transparent`: Directly uses the inner type's Display implementation.
* `UpperCase`: Converts the inner value to uppercase before displaying.
* `LowerCase`: Converts the inner value to lowercase before displaying.
* `OpaqueUpperCase`: Formats the output as TypeName(VALUE) where VALUE is uppercase.
* `OpaqueLowerCase`: Formats the output as TypeName(value) where value is lowercase.
* `Custom string`: Allows for a custom format string

#### Examples
```rust
#[derive(Synonym)]
#[synonym(display = "UpperCase")]
struct CountryName(String);

#[derive(Synonym)]
#[synonym(display = "::<> {} <>::")]
struct Turbo(String);
```

### Serde Support

To enable Serde support for serialization and deserialization, you'll need to enable the `with_serde` feature flag in your `Cargo.toml`:

```toml
[dependencies]
synonym = { version = "0.1.5", features = ["with_serde"] }
```

With this feature enabled, the `Serialize` and `Deserialize` traits will be automatically implemented for your type.

---
This documentation was generated with the assistance of ChatGPT-4 by OpenAI.

## License

Licensed under of MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT)

### Contribution

All contributions and comments are more than welcome! Don't be afraid to open an issue or PR whenever you find a bug or have an idea to improve this crate.