Skip to content

Commit

Permalink
update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
magiclen committed Jun 1, 2024
1 parent f962522 commit 47bd92f
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 12 deletions.
82 changes: 71 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,11 @@ enum Enum<T, K> {

In the above case, `T` is bound to the `Debug` trait, but `K` is not.

Or, you can have `educe` replicate the behaviour of `std`'s `derive`'s,
where a bound is produced for *every* generic parameter,
without regard to how it's used in the structure:
Or, you can have `educe` replicate the behaviour of `std`'s `derive`'s, where a bound is produced for *every* generic parameter, without regard to how it's used in the structure:

```rust
use educe::Educe;

#[derive(Educe)]
#[educe(Debug(bound(*)))]
struct Struct<T> {
Expand All @@ -224,13 +224,7 @@ struct Struct<T> {
}
```

This can be useful if you don't want to make the trait implementation
part of your permanent public API.
In this example,
`Struct<T>` doesn't implement `Debug` unless `T` does.
I.e., it has a `T: Debug` bound even though that's not needed right now.
Later we might want to display `f`; we wouldn't then need to make
a breaking API change by adding the bound.
This can be useful if you don't want to make the trait implementation part of your permanent public API. In this example, `Struct<T>` doesn't implement `Debug` unless `T` does. I.e., it has a `T: Debug` bound even though that's not needed right now. Later we might want to display `f`; we wouldn't then need to make a breaking API change by adding the bound.

This was the behaviour of `Trait(bound)` in educe 0.4.x and earlier.

Expand Down Expand Up @@ -358,6 +352,27 @@ enum Enum<T, K: A> {

In the above case, `T` is bound to the `Clone` trait, but `K` is not.

Or, you can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.

```rust
use educe::Educe;

trait A {
fn add(&self, rhs: u8) -> Self;
}

fn clone<T: A>(v: &T) -> T {
v.add(100)
}

#[derive(Educe)]
#[educe(Clone(bound(*)))]
struct Struct<T: A> {
#[educe(Clone(method(clone)))]
f: T,
}
```

###### Union

Refer to the introduction of the `#[educe(Copy)]` attribute.
Expand Down Expand Up @@ -587,6 +602,21 @@ enum Enum<T, K> {
}
```

In the above case, `T` is bound to the `PartialEq` trait, but `K` is not.

You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.

```rust
use educe::Educe;

#[derive(Educe)]
#[educe(PartialEq(bound(*)))]
struct Struct<T> {
#[educe(PartialEq(ignore))]
f: T,
}
```

###### Union

The `#[educe(PartialEq(unsafe))]` attribute can be used for a union. The fields of a union cannot be compared with other methods. The implementation is **unsafe** because it disregards the specific fields it utilizes.
Expand Down Expand Up @@ -918,7 +948,7 @@ fn partial_cmp<T: A>(a: &T, b: &T) -> Option<Ordering> {
}

#[derive(PartialEq, Educe)]
#[educe(PartialOrd(bound(T: std::cmp::PartialOrd, K: std::cmp::PartialOrd + A)))]
#[educe(PartialOrd(bound(T: std::cmp::PartialOrd, K: PartialEq + A)))]
enum Enum<T, K> {
V1,
V2 {
Expand All @@ -931,6 +961,21 @@ enum Enum<T, K> {
}
```

In the above case, `T` is bound to the `PartialOrd` trait, but `K` is not.

You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.

```rust
use educe::Educe;

#[derive(PartialEq, Educe)]
#[educe(PartialOrd(bound(*)))]
struct Struct<T> {
#[educe(PartialOrd(ignore))]
f: T,
}
```

#### Ord

Use `#[derive(Educe)]` and `#[educe(Ord)]` to implement the `Ord` trait for a struct or enum. You can also choose to ignore specific fields or set a method to replace the `Ord` trait.
Expand Down Expand Up @@ -1245,6 +1290,21 @@ enum Enum<T, K> {
}
```

In the above case, `T` is bound to the `Hash` trait, but `K` is not.

You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.

```rust
use educe::Educe;

#[derive(Educe)]
#[educe(Hash(bound(*)))]
struct Struct<T> {
#[educe(Hash(ignore))]
f: T,
}
```

###### Union

The `#[educe(PartialEq(unsafe), Eq, Hash(unsafe))]` attribute can be used for a union. The fields of a union cannot be hashed with other methods. The implementation is **unsafe** because it disregards the specific fields it utilizes.
Expand Down
118 changes: 117 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,26 @@ enum Enum<T, K> {
In the above case, `T` is bound to the `Debug` trait, but `K` is not.
Or, you can have `educe` replicate the behaviour of `std`'s `derive`'s, where a bound is produced for *every* generic parameter, without regard to how it's used in the structure:
```rust
# #[cfg(feature = "Debug")]
# {
use educe::Educe;
#[derive(Educe)]
#[educe(Debug(bound(*)))]
struct Struct<T> {
#[educe(Debug(ignore))]
f: T,
}
# }
```
This can be useful if you don't want to make the trait implementation part of your permanent public API. In this example, `Struct<T>` doesn't implement `Debug` unless `T` does. I.e., it has a `T: Debug` bound even though that's not needed right now. Later we might want to display `f`; we wouldn't then need to make a breaking API change by adding the bound.
This was the behaviour of `Trait(bound)` in educe 0.4.x and earlier.
###### Union
A union will be formatted as a `u8` slice because we don't know its fields at runtime. The fields of a union cannot be ignored, renamed, or formatted with other methods. The implementation is **unsafe** because it may expose uninitialized memory.
Expand Down Expand Up @@ -369,6 +389,30 @@ enum Enum<T, K: A> {
In the above case, `T` is bound to the `Clone` trait, but `K` is not.
Or, you can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.
```rust
# #[cfg(feature = "Clone")]
# {
use educe::Educe;
trait A {
fn add(&self, rhs: u8) -> Self;
}
fn clone<T: A>(v: &T) -> T {
v.add(100)
}
#[derive(Educe)]
#[educe(Clone(bound(*)))]
struct Struct<T: A> {
#[educe(Clone(method(clone)))]
f: T,
}
# }
```
###### Union
Refer to the introduction of the `#[educe(Copy)]` attribute.
Expand Down Expand Up @@ -625,6 +669,24 @@ enum Enum<T, K> {
# }
```
In the above case, `T` is bound to the `PartialEq` trait, but `K` is not.
You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.
```rust
# #[cfg(feature = "PartialEq")]
# {
use educe::Educe;
#[derive(Educe)]
#[educe(PartialEq(bound(*)))]
struct Struct<T> {
#[educe(PartialEq(ignore))]
f: T,
}
# }
```
###### Union
The `#[educe(PartialEq(unsafe))]` attribute can be used for a union. The fields of a union cannot be compared with other methods. The implementation is **unsafe** because it disregards the specific fields it utilizes.
Expand Down Expand Up @@ -997,7 +1059,7 @@ fn partial_cmp<T: A>(a: &T, b: &T) -> Option<Ordering> {
}
#[derive(PartialEq, Educe)]
#[educe(PartialOrd(bound(T: std::cmp::PartialOrd, K: std::cmp::PartialOrd + A)))]
#[educe(PartialOrd(bound(T: std::cmp::PartialOrd, K: PartialEq + A)))]
enum Enum<T, K> {
V1,
V2 {
Expand All @@ -1011,6 +1073,42 @@ enum Enum<T, K> {
# }
```
In the above case, `T` is bound to the `PartialOrd` trait, but `K` is not.
You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.
```rust
# #[cfg(feature = "PartialOrd")]
# {
use educe::Educe;
#[derive(PartialEq, Educe)]
#[educe(PartialOrd(bound(*)))]
struct Struct<T> {
#[educe(PartialOrd(ignore))]
f: T,
}
# }
```
###### Union
The `#[educe(PartialEq(unsafe))]` attribute can be used for a union. The fields of a union cannot be compared with other methods. The implementation is **unsafe** because it disregards the specific fields it utilizes.
```rust
# #[cfg(feature = "PartialEq")]
# {
use educe::Educe;
#[derive(Educe)]
#[educe(PartialEq(unsafe))]
union Union {
f1: u8,
f2: i32
}
# }
```
#### Ord
Use `#[derive(Educe)]` and `#[educe(Ord)]` to implement the `Ord` trait for a struct or enum. You can also choose to ignore specific fields or set a method to replace the `Ord` trait.
Expand Down Expand Up @@ -1361,6 +1459,24 @@ enum Enum<T, K> {
# }
```
In the above case, `T` is bound to the `Hash` trait, but `K` is not.
You can have `educe` replicate the behaviour of `std`'s `derive`'s by using `bound(*)`. See the [`Debug`](#debug) section for more information.
```rust
# #[cfg(feature = "Hash")]
# {
use educe::Educe;
#[derive(Educe)]
#[educe(Hash(bound(*)))]
struct Struct<T> {
#[educe(Hash(ignore))]
f: T,
}
# }
```
###### Union
The `#[educe(PartialEq(unsafe), Eq, Hash(unsafe))]` attribute can be used for a union. The fields of a union cannot be hashed with other methods. The implementation is **unsafe** because it disregards the specific fields it utilizes.
Expand Down

0 comments on commit 47bd92f

Please sign in to comment.