Skip to content

Commit

Permalink
Refactor AsRef and AsMut derives implementation (#286)
Browse files Browse the repository at this point in the history
## Synopsis

This PR is a part of replacing all attributes having `syn::Meta` syntax
to custom parsing, similarly to #241, #248.

Paves the way for #285, and possibly other enhancements such as an
opt-in #123.


## Solution

Implement custom attribute parsing without `utils::State`.

Co-authored-by: Kai Ren <tyranron@gmail.com>
  • Loading branch information
MegaBluejay and tyranron committed Aug 18, 2023
1 parent de4f141 commit 6a444a3
Show file tree
Hide file tree
Showing 52 changed files with 1,806 additions and 366 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ required-features = ["try_unwrap"]
[[test]]
name = "compile_fail"
path = "tests/compile_fail/mod.rs"
required-features = ["debug", "display", "from", "into"]
required-features = ["as_ref", "as_mut", "debug", "display", "from", "into"]

[[test]]
name = "no_std"
Expand Down
27 changes: 21 additions & 6 deletions impl/doc/as_mut.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ This generates:

```rust
# struct SingleFieldForward(Vec<i32>);
impl<__AsMutT: ?::core::marker::Sized> ::core::convert::AsMut<__AsMutT> for SingleFieldForward
impl<__AsT: ?::core::marker::Sized> ::core::convert::AsMut<__AsT> for SingleFieldForward
where
Vec<i32>: ::core::convert::AsMut<__AsMutT>,
Vec<i32>: ::core::convert::AsMut<__AsT>,
{
#[inline]
fn as_mut(&mut self) -> &mut __AsMutT {
<Vec<i32> as ::core::convert::AsMut<__AsMutT>>::as_mut(&mut self.0)
fn as_mut(&mut self) -> &mut __AsT {
<Vec<i32> as ::core::convert::AsMut<__AsT>>::as_mut(&mut self.0)
}
}
```
Expand All @@ -69,7 +69,7 @@ where
When `AsMut` is derived for a struct with more than one field (including tuple
structs), you must also mark one or more fields with the `#[as_mut]` attribute.
An implementation will be generated for each indicated field.
You can also exclude a specific field by using `#[as_mut(ignore)]`.
You can also exclude a specific field by using `#[as_mut(ignore)]` (or `#[as_mut(ignore)]`).

```rust
# use derive_more::AsMut;
Expand Down Expand Up @@ -121,8 +121,23 @@ struct MyWrapper {
}
```

Similarly, if some field is annotated with `#[as_mut(forward)]`, no other
field can be marked.


```rust,compile_fail
# use derive_more::AsMut;
#
// Error! Conflicting implementations of `AsMut<i32>`
// note: upstream crates may add a new impl of trait `AsMut<i32>`
// for type `String` in future versions
#[derive(AsMut)]
struct ForwardWithOther {
#[as_mut(forward)]
str: String,
#[as_mut]
number: i32,
}
```

## Enums

Expand Down
27 changes: 21 additions & 6 deletions impl/doc/as_ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,13 @@ This generates:

```rust
# struct SingleFieldForward(Vec<i32>);
impl<__AsRefT: ?::core::marker::Sized> ::core::convert::AsRef<__AsRefT> for SingleFieldForward
impl<__AsT: ?::core::marker::Sized> ::core::convert::AsRef<__AsT> for SingleFieldForward
where
Vec<i32>: ::core::convert::AsRef<__AsRefT>,
Vec<i32>: ::core::convert::AsRef<__AsT>,
{
#[inline]
fn as_ref(&self) -> &__AsRefT {
<Vec<i32> as ::core::convert::AsRef<__AsRefT>>::as_ref(&self.0)
fn as_ref(&self) -> &__AsT {
<Vec<i32> as ::core::convert::AsRef<__AsT>>::as_ref(&self.0)
}
}
```
Expand All @@ -69,7 +69,7 @@ where
When `AsRef` is derived for a struct with more than one field (including tuple
structs), you must also mark one or more fields with the `#[as_ref]` attribute.
An implementation will be generated for each indicated field.
You can also exclude a specific field by using `#[as_ref(ignore)]`.
You can also exclude a specific field by using `#[as_ref(skip)]` (or `#[as_ref(ignore)]`).

```rust
# use derive_more::AsRef;
Expand Down Expand Up @@ -122,8 +122,23 @@ struct MyWrapper {
}
```

Similarly, if some field is annotated with `#[as_ref(forward)]`, no other
field can be marked.


```rust,compile_fail
# use derive_more::AsRef;
#
// Error! Conflicting implementations of `AsRef<i32>`
// note: upstream crates may add a new impl of trait `AsRef<i32>`
// for type `String` in future versions
#[derive(AsRef)]
struct ForwardWithOther {
#[as_ref(forward)]
str: String,
#[as_ref]
number: i32,
}
```

## Enums

Expand Down

0 comments on commit 6a444a3

Please sign in to comment.