derive_more
derive_more copied to clipboard
List of potential derives
I really like this crate, and would love to see one crate that did what you would expect for std traits. So I was thinking about compiling a list of other potential derives:
Conversions:
- [x]
AsMut - [x]
AsRef
Borrowing:
- [ ]
Borrow - [ ]
BorrowMut - [ ]
ToOwned
Ops:
- [x]
Index,IndexMut - [x]
Deref,DerefMut
Formatting:
- [x]
Display - [x]
Binary,Octal,LowerHex,UpperHex,LowerExp,UpperExp,Pointer(by generalizingDisplayimplementation)
Any thought about these? I wouldn't mind hashing out some of the details and even contributing.
It's unclear to me how one would implement the ones I crossed off. One option would be to just allow one to pass in the type parameter via a string like: #[Derive(Index)] #[Index("usize")] assuming the inner type satisfies Index<usize>. But this seems very unhygienic and might be worth waiting for later.
Hi Christopher, thanks for the suggestions. I don't think Display should ever output debug output. That division is there for a reason. Furthermore, I don't think there's a general enough solution for displaying a struct with multiple fields. Structs with a single field would make sense though. The same I think is true for all of the other traits you mention (except maybe deref).
So deriving these for newtypes should be quite easy. Even the ones you crossed off should be possible, because you can use generics there (see the Mul like traits for an example). As a next step it would be cool to be able to mark one of the fields of a multi field struct with #[Display] to indicate that it should forward display to that field.
I don't really have time to implement these features in the near future though. If you would like to try it's fine though and I'll try to free up some time to merge a PR.
Hey @cbreeden, I changed your comment at the top a bit for an easy checklist. I hope you're fine with that. Display is now implemented on master for newtypes btw.
Please add Deref/DerefMut like https://crates.io/crates/shrinkwraprs
I have a deref branch at the moment (not merged because I haven't made the docs yet), but it is quite different from shrinkwraprs. It will just forward the operations to the member. I like the shrinkwraprs idea, but I don't think it makes sense to have this behaviour as the default. You can still use shrinkwraprs combined with derive_more if you want its behaviour for Deref/DerefMut.
I haven't used shrinkwraprs before, how is its Deref impl different to your approach?
I've just released v0.10.0 with Deref and DerefMut support. Example usage and generated code can be found here:
https://jeltef.github.io/derive_more/derive_more/deref.html
https://jeltef.github.io/derive_more/derive_more/deref_mut.html
I think those links should show the difference in usage with this: https://crates.io/crates/shrinkwraprs
Does it only work for members that also impl Deref?
Any further discussion needed before AsRef and AsMut are implemented? Newtypes are pretty straightforward, but if we want to do it for other structs, it's not as easy and would probably require parameterization of the desired fields - otherwise it won't know how to handle multiple fields of the same type. I wouldn't know how to do that, but I may be able to contribute the newtype definition.
@AGausmann for structs with multiple fields, I think it would make sense for each field to "opt in" to the AsRef derivation via an attribute. Something like this:
#[derive(AsRef)]
struct Foo {
#[as_ref]
bar: Bar,
// Generates impl AsRef<Bar> for Foo { ... }
#[as_ref]
baz: Baz,
// Generates impl AsRef<Baz> for Foo { ... }
}
I don't think it's possible to implement AsRef multiple times for different fields of the same type. For instance, trying to derive AsRef as follows should result in an error:
#[derive(AsRef)]
struct Foo {
#[as_ref]
bar1: Bar,
// Error! Can't implement AsRef<Bar> multiple times
#[as_ref]
bar2: Bar,
}
@JelteF would you be willing to accept a PR that adds AsRef and AsMut support as described above?
Yes, that sounds like a good idea.
On Wed, 11 Sep 2019, 02:19 Bobby Reynolds, [email protected] wrote:
@AGausmann https://github.com/AGausmann for structs with multiple fields, I think it would make sense for each field to "opt in" to the AsRef derivation via an attribute. Something like this:
#[derive(AsRef)]struct Foo {
#[as_ref] bar: Bar, // Generates impl AsRef<Bar> for Foo { ... } #[as_ref] baz: Baz, // Generates impl AsRef<Baz> for Foo { ... }}
I don't think it's possible to implement AsRef multiple times for different fields of the same type. For instance, trying to derive AsRef as follows should result in an error:
#[derive(AsRef)]struct Foo {
#[as_ref] bar1: Bar, // Error! Can't implement AsRef<Bar> multiple times #[as_ref] bar2: Bar,}
@JelteF https://github.com/JelteF would you be willing to accept a PR that adds AsRef and AsMut support as described above?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JelteF/derive_more/issues/25?email_source=notifications&email_token=AAI3YJRNLSZ7HYLJJ52BQ2LQJA2SBA5CNFSM4DNWL3O2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6M3T3Y#issuecomment-530168303, or mute the thread https://github.com/notifications/unsubscribe-auth/AAI3YJVAXR4ZOFQBWRHZC3TQJA2SBANCNFSM4DNWL3OQ .
I'd avoid using multiple top-level attributes. It would be better to use a single attribute name like #[derive_more(as_ref, as_mut)], similar to the pattern that Serde uses.
@AGausmann on one hand that makes sense, but we already do that for the display style attributes. So I think it's okay to have them as top level ones to stay consistent. Furthermore I'm not sure if you can provide arguments to non top level atributes, which would probably be nice given this issue: https://github.com/JelteF/derive_more/issues/60 There you could use #[from(ignore)]
@JelteF is #[derive(Error)] would be desirable? I've tried several err derive crates out there and they provide custom display capabilities for ergonomics, which, however, do not mix with our #[derive(Display)] well.
What I propose is to add simple #[derive(Error)] to derive_more which will derive only std::error::Error implementation. Without any implicit From and Display implementations. This will play very well with existing #[derive(Display)] and #[derive(From)] macros.
If it's acceptable, I'll roll-out implementation in a few working days.
Derives for any standard library traits fit in this library, so also for Error. So I'm definitely open to a PR. I'm not entirely sure how you would want to derive error. Could you make a separate issue for that with your general idea as a place to discuss the API/ergonomics? (a PR is also fine if you already have some code).
On Fri, 11 Oct 2019, 17:10 Kai Ren, [email protected] wrote:
@JelteF https://github.com/JelteF is #[derive(Error)] would be desirable? I've tried several err derive crates out there https://crates.io/search?q=error%20derive and they provide custom display capabilities for ergonomics, which, however, do not mix with our #[derive(Display)] well.
What I propose is to add simple #[derive(Error)] to derive_more which will derive only std::error::Error implementation. Without any implicit From and Display implementations. This will play very well with existing #[derive(Display)] and #[derive(From)] macros.
If it's acceptable, I'll roll-out implementation in a few working days.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JelteF/derive_more/issues/25?email_source=notifications&email_token=AAI3YJTCUXA65PO6TLS5F3TQOCJQDA5CNFSM4DNWL3O2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBAJTVI#issuecomment-541104597, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAI3YJVI5CROE7KDWYBMFVTQOCJQDANCNFSM4DNWL3OQ .
I ran into a situation where I'd love to be able to use the formatting system in #[derive(Display)] with Debug (for situations where not all of the fields are Debug). Does this make sense?
You should be able to use #[derive(DebugCustom)] for that.