diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/derive_more-impl/doc | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/derive_more-impl/doc')
24 files changed, 2823 insertions, 0 deletions
diff --git a/third_party/rust/derive_more-impl/doc/add.md b/third_party/rust/derive_more-impl/doc/add.md new file mode 100644 index 0000000000..5d58996a28 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/add.md @@ -0,0 +1,152 @@ +# What `#[derive(Add)]` generates + +The derived `Add` implementation will allow two structs from the same type to be +added together. This done by adding their respective fields together and +creating a new struct with those values. +For enums each variant can be added in a similar way to another instance of that +same variant. There's one big difference however, it returns a +`Result<EnumType>`, because an error is returned when to different variants are +added together. + + + + +## Tuple structs + +When deriving `Add` for a tuple struct with two fields like this: + +```rust +# use derive_more::Add; +# +#[derive(Add)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl ::core::ops::Add for MyInts { + type Output = MyInts; + fn add(self, rhs: MyInts) -> MyInts { + MyInts(self.0.add(rhs.0), self.1.add(rhs.1)) + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Regular structs + +When deriving `Add` for a regular struct with two fields like this: + +```rust +# use derive_more::Add; +# +#[derive(Add)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl ::core::ops::Add for Point2D { + type Output = Point2D; + fn add(self, rhs: Point2D) -> Point2D { + Point2D { + x: self.x.add(rhs.x), + y: self.y.add(rhs.y), + } + } +} +``` + +The behaviour is similar for more or less fields. + + + + +## Enums + +There's a big difference between the code that is generated for the two struct +types and the one that is generated for enums. The code for enums returns +`Result<EnumType>` instead of an `EnumType` itself. This is because adding an +enum to another enum is only possible if both are the same variant. This makes +the generated code much more complex as well, because this check needs to be +done. For instance when deriving `Add` for an enum like this: + +```rust +# use derive_more::Add; +# +#[derive(Add)] +enum MixedInts { + SmallInt(i32), + BigInt(i64), + TwoSmallInts(i32, i32), + NamedSmallInts { x: i32, y: i32 }, + UnsignedOne(u32), + UnsignedTwo(u32), + Unit, +} +``` + +Code like this will be generated: + +```rust +# enum MixedInts { +# SmallInt(i32), +# BigInt(i64), +# TwoSmallInts(i32, i32), +# NamedSmallInts { x: i32, y: i32 }, +# UnsignedOne(u32), +# UnsignedTwo(u32), +# Unit, +# } +impl ::core::ops::Add for MixedInts { + type Output = Result<MixedInts, ::derive_more::ops::BinaryError>; + fn add(self, rhs: MixedInts) -> Result<MixedInts, ::derive_more::ops::BinaryError> { + match (self, rhs) { + (MixedInts::SmallInt(__l_0), MixedInts::SmallInt(__r_0)) => { + Ok(MixedInts::SmallInt(__l_0.add(__r_0))) + } + (MixedInts::BigInt(__l_0), MixedInts::BigInt(__r_0)) => { + Ok(MixedInts::BigInt(__l_0.add(__r_0))) + } + (MixedInts::TwoSmallInts(__l_0, __l_1), MixedInts::TwoSmallInts(__r_0, __r_1)) => { + Ok(MixedInts::TwoSmallInts(__l_0.add(__r_0), __l_1.add(__r_1))) + } + (MixedInts::NamedSmallInts { x: __l_0, y: __l_1 }, + MixedInts::NamedSmallInts { x: __r_0, y: __r_1 }) => { + Ok(MixedInts::NamedSmallInts { + x: __l_0.add(__r_0), + y: __l_1.add(__r_1), + }) + } + (MixedInts::UnsignedOne(__l_0), MixedInts::UnsignedOne(__r_0)) => { + Ok(MixedInts::UnsignedOne(__l_0.add(__r_0))) + } + (MixedInts::UnsignedTwo(__l_0), MixedInts::UnsignedTwo(__r_0)) => { + Ok(MixedInts::UnsignedTwo(__l_0.add(__r_0))) + } + (MixedInts::Unit, MixedInts::Unit) => Err(::derive_more::ops::BinaryError::Unit( + ::derive_more::ops::UnitError::new("add"), + )), + _ => Err(::derive_more::ops::BinaryError::Mismatch( + ::derive_more::ops::WrongVariantError::new("add"), + )), + } + } +} +``` + +Also note the Unit type that throws an error when adding it to itself. diff --git a/third_party/rust/derive_more-impl/doc/add_assign.md b/third_party/rust/derive_more-impl/doc/add_assign.md new file mode 100644 index 0000000000..04a85a186b --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/add_assign.md @@ -0,0 +1,78 @@ +# What `#[derive(AddAssign)]` generates + +This code is very similar to the code that is generated for `#[derive(Add)]`. +The difference is that it mutates the existing instance instead of creating a +new one. + + + + +## Tuple structs + +When deriving `AddAssign` for a tuple struct with two fields like this: + +```rust +# use derive_more::AddAssign; +# +#[derive(AddAssign)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl ::core::ops::AddAssign for MyInts { + fn add_assign(&mut self, rhs: MyInts) { + self.0.add_assign(rhs.0); + self.1.add_assign(rhs.1); + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Regular structs + +When deriving for a regular struct with two fields like this: + +```rust +# use derive_more::AddAssign; +# +#[derive(AddAssign)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl ::core::ops::AddAssign for Point2D { + fn add_assign(&mut self, rhs: Point2D) { + self.x.add_assign(rhs.x); + self.y.add_assign(rhs.y); + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Enums + +Deriving `AddAssign` is not (yet) supported for enums. +This is mostly due to the fact that it is not trivial convert the `Add` +derivation code, because that returns a `Result<EnumType>` instead of an +`EnumType`. +Handling the case where it errors would be hard and maybe impossible. diff --git a/third_party/rust/derive_more-impl/doc/as_mut.md b/third_party/rust/derive_more-impl/doc/as_mut.md new file mode 100644 index 0000000000..a1e6127d3a --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/as_mut.md @@ -0,0 +1,129 @@ +# What `#[derive(AsMut)]` generates + +Deriving `AsMut` generates one or more implementations of `AsMut`, each +corresponding to one of the fields of the decorated type. +This allows types which contain some `T` to be passed anywhere that an +`AsMut<T>` is accepted. + + + + +## Newtypes and Structs with One Field + +When `AsMut` is derived for a newtype or struct with one field, a single +implementation is generated to expose the underlying field. + +```rust +# use derive_more::AsMut; +# +#[derive(AsMut)] +struct MyWrapper(String); +``` + +Generates: + +```rust +# struct MyWrapper(String); +impl AsMut<String> for MyWrapper { + fn as_mut(&mut self) -> &mut String { + &mut self.0 + } +} +``` + +It's also possible to use the `#[as_mut(forward)]` attribute to forward +to the `as_mut` implementation of the field. So here `SingleFieldForward` +implements all `AsMut` for all types that `Vec<i32>` implements `AsMut` for. + +```rust +# use derive_more::AsMut; +# +#[derive(AsMut)] +#[as_mut(forward)] +struct SingleFieldForward(Vec<i32>); + +let mut item = SingleFieldForward(vec![]); +let _: &mut [i32] = (&mut item).as_mut(); +``` + +This generates: + +```rust +# struct SingleFieldForward(Vec<i32>); +impl<__AsMutT: ?::core::marker::Sized> ::core::convert::AsMut<__AsMutT> for SingleFieldForward +where + Vec<i32>: ::core::convert::AsMut<__AsMutT>, +{ + #[inline] + fn as_mut(&mut self) -> &mut __AsMutT { + <Vec<i32> as ::core::convert::AsMut<__AsMutT>>::as_mut(&mut self.0) + } +} +``` + + + + +## Structs with Multiple Fields + +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)]`. + +```rust +# use derive_more::AsMut; +# +#[derive(AsMut)] +struct MyWrapper { + #[as_mut] + name: String, + #[as_mut] + num: i32, + valid: bool, +} +``` + +Generates: + +```rust +# struct MyWrapper { +# name: String, +# num: i32, +# valid: bool, +# } +impl AsMut<String> for MyWrapper { + fn as_mut(&mut self) -> &mut String { + &mut self.name + } +} + +impl AsMut<i32> for MyWrapper { + fn as_mut(&mut self) -> &mut i32 { + &mut self.num + } +} +``` + +Note that `AsMut<T>` may only be implemented once for any given type `T`. This means any attempt to +mark more than one field of the same type with `#[as_mut]` will result in a compilation error. + +```rust,compile_fail +# use derive_more::AsMut; +# +// Error! Conflicting implementations of AsMut<String> +#[derive(AsMut)] +struct MyWrapper { + #[as_mut] + str1: String, + #[as_mut] + str2: String, +} +``` + + + + +## Enums + +Deriving `AsMut` for enums is not supported. diff --git a/third_party/rust/derive_more-impl/doc/as_ref.md b/third_party/rust/derive_more-impl/doc/as_ref.md new file mode 100644 index 0000000000..112ba15a1c --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/as_ref.md @@ -0,0 +1,130 @@ +# What `#[derive(AsRef)]` generates + +Deriving `AsRef` generates one or more implementations of `AsRef`, each +corresponding to one of the fields of the decorated type. +This allows types which contain some `T` to be passed anywhere that an +`AsRef<T>` is accepted. + + + + +## Newtypes and Structs with One Field + +When `AsRef` is derived for a newtype or struct with one field, a single +implementation is generated to expose the underlying field. + +```rust +# use derive_more::AsRef; +# +#[derive(AsRef)] +struct MyWrapper(String); +``` + +Generates: + +```rust +# struct MyWrapper(String); +impl AsRef<String> for MyWrapper { + fn as_ref(&self) -> &String { + &self.0 + } +} +``` + +It's also possible to use the `#[as_ref(forward)]` attribute to forward +to the `as_ref` implementation of the field. So here `SingleFieldForward` +implements all `AsRef` for all types that `Vec<i32>` implements `AsRef` for. + +```rust +# use derive_more::AsRef; +# +#[derive(AsRef)] +#[as_ref(forward)] +struct SingleFieldForward(Vec<i32>); + +let item = SingleFieldForward(vec![]); +let _: &[i32] = (&item).as_ref(); +``` + +This generates: + +```rust +# struct SingleFieldForward(Vec<i32>); +impl<__AsRefT: ?::core::marker::Sized> ::core::convert::AsRef<__AsRefT> for SingleFieldForward +where + Vec<i32>: ::core::convert::AsRef<__AsRefT>, +{ + #[inline] + fn as_ref(&self) -> &__AsRefT { + <Vec<i32> as ::core::convert::AsRef<__AsRefT>>::as_ref(&self.0) + } +} +``` + + + + +## Structs with Multiple Fields + +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)]`. + +```rust +# use derive_more::AsRef; +# +#[derive(AsRef)] +struct MyWrapper { + #[as_ref] + name: String, + #[as_ref] + num: i32, + valid: bool, +} +``` + +Generates: + +```rust +# struct MyWrapper { +# name: String, +# num: i32, +# valid: bool, +# } +impl AsRef<String> for MyWrapper { + fn as_ref(&self) -> &String { + &self.name + } +} + +impl AsRef<i32> for MyWrapper { + fn as_ref(&self) -> &i32 { + &self.num + } +} +``` + +Note that `AsRef<T>` may only be implemented once for any given type `T`. +This means any attempt to mark more than one field of the same type with +`#[as_ref]` will result in a compilation error. + +```rust,compile_fail +# use derive_more::AsRef; +# +// Error! Conflicting implementations of AsRef<String> +#[derive(AsRef)] +struct MyWrapper { + #[as_ref] + str1: String, + #[as_ref] + str2: String, +} +``` + + + + +## Enums + +Deriving `AsRef` for enums is not supported. diff --git a/third_party/rust/derive_more-impl/doc/constructor.md b/third_party/rust/derive_more-impl/doc/constructor.md new file mode 100644 index 0000000000..43f55c06d6 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/constructor.md @@ -0,0 +1,80 @@ +# What `#[derive(Constructor)]` generates + +A common pattern in Rust is to create a static constructor method called +`new`. This method is can then be used to create an instance of a struct. You +can now derive this method by using `#[derive(Constructor)]`, even though +`Constructor` it is not an actual trait. The generated `new` method is very +similar to the `from` method when deriving `From`, except that it takes multiple +arguments instead of a tuple. + + + + +## Tuple structs + +When deriving `Constructor` for a tuple struct with a two fields like this: + +```rust +# use derive_more::Constructor; +# +#[derive(Constructor)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl MyInts { + pub const fn new(__0: i32, __1: i32) -> MyInts { + MyInts(__0, __1) + } +} +``` + +The generated code is similar for more or less fields. + + + + +## Regular structs + +For regular structs almost the same code is generated as for tuple structs +except that it assigns the fields differently. + +```rust +# use derive_more::Constructor; +# +#[derive(Constructor)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl Point2D { + pub const fn new(x: i32, y: i32) -> Point2D { + Point2D { x: x, y: y } + } +} +``` + +The generated code is similar for more or less fields. + + + + +## Enums + +Currently `Constructor` cannot be derived for enums. This is because the `new` +method might then need to have a different number of arguments. This is +currently not supported by Rust. So this functionality will not be added until +this [RFC](https://github.com/rust-lang/rfcs/issues/376) (or a similar one) is +accepted and implemented. diff --git a/third_party/rust/derive_more-impl/doc/debug.md b/third_party/rust/derive_more-impl/doc/debug.md new file mode 100644 index 0000000000..b643976d04 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/debug.md @@ -0,0 +1,126 @@ +# What `#[derive(Debug)]` generates + +This derive macro is a clever superset of `Debug` from standard library. Additional features include: +- not imposing redundant trait bounds; +- `#[debug(skip)]` attribute to skip formatting struct field or enum variant; +- `#[debug("...", args...)]` to specify custom formatting for a particular struct or enum variant field; +- `#[debug(bounds(...))]` to impose additional custom trait bounds. + + + + +## The format of the format + +You supply a format by placing an attribute on particular struct or enum variant field (not enum variant itself): +`#[debug("...", args...)]`. The format is exactly like in [`format!()`] or any other [`format_args!()`]-based macros. + +The variables available in the arguments is `self` and each member of the variant, with members of tuple structs being +named with a leading underscore and their index, i.e. `_0`, `_1`, `_2`, etc. + + + + +### Generic data types + +When deriving `Debug` for a generic struct/enum, all generic type arguments _used_ during formatting +are bound by respective formatting trait. + +E.g., for a structure `Foo` defined like this: +```rust +use derive_more::Debug; + +#[derive(Debug)] +struct Foo<'a, T1, T2: Trait, T3, T4> { + #[debug("{a}")] + a: T1, + #[debug("{b}")] + b: <T2 as Trait>::Type, + #[debug("{c:?}")] + c: Vec<T3>, + #[debug("{d:p}")] + d: &'a T1, + #[debug(skip)] + e: T4, +} + +trait Trait { type Type; } +``` + +The following where clauses would be generated: +* `T1: Display + Pointer` +* `<T2 as Trait>::Type: Debug` +* `Bar<T3>: Display` + + + + +### Custom trait bounds + +Sometimes you may want to specify additional trait bounds on your generic type parameters, so that they could be used +during formatting. This can be done with a `#[debug(bound(...))]` attribute. + +`#[debug(bound(...))]` accepts code tokens in a format similar to the format used in angle bracket list (or `where` +clause predicates): `T: MyTrait, U: Trait1 + Trait2`. + +Using `#[debug("...", ...)]` formatting we'll try our best to infer trait bounds, but in more advanced cases this isn't +possible. Our aim is to avoid imposing additional bounds, as they can be added with `#[debug(bound(...))]`. +In the example below, we can infer only that `V: Display`, other bounds have to be supplied by the user: + +```rust +use std::fmt::Display; +use derive_more::Debug; + +#[derive(Debug)] +#[debug(bound(T: MyTrait, U: Display))] +struct MyStruct<T, U, V, F> { + #[debug("{}", a.my_function())] + a: T, + #[debug("{}", b.to_string().len())] + b: U, + #[debug("{c}")] + c: V, + #[debug(skip)] + d: F, +} + +trait MyTrait { fn my_function(&self) -> i32; } +``` + + + + +## Example usage + +```rust +use std::path::PathBuf; +use derive_more::Debug; + +#[derive(Debug)] +struct MyInt(i32); + +#[derive(Debug)] +struct MyIntHex(#[debug("{_0:x}")] i32); + +#[derive(Debug)] +enum E { + Skipped { + x: u32, + #[debug(skip)] + y: u32, + }, + Binary { + #[debug("{i:b}")] + i: i8, + }, + Path(#[debug("{}", _0.display())] PathBuf), +} + +assert_eq!(format!("{:?}", MyInt(-2)), "MyInt(-2)"); +assert_eq!(format!("{:?}", MyIntHex(-255)), "MyIntHex(ffffff01)"); +assert_eq!(format!("{:?}", E::Skipped { x: 10, y: 20 }), "Skipped { x: 10, .. }"); +assert_eq!(format!("{:?}", E::Binary { i: -2 }), "Binary { i: 11111110 }"); +assert_eq!(format!("{:?}", E::Path("abc".into())), "Path(abc)"); +``` + +[`format!()`]: https://doc.rust-lang.org/stable/std/macro.format.html +[`format_args!()`]: https://doc.rust-lang.org/stable/std/macro.format_args.html diff --git a/third_party/rust/derive_more-impl/doc/deref.md b/third_party/rust/derive_more-impl/doc/deref.md new file mode 100644 index 0000000000..f1719e9b16 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/deref.md @@ -0,0 +1,107 @@ +# Using `#[derive(Deref)]` + +Deriving `Deref` only works for a single field of a struct. +It's possible to use it in two ways: + +1. Dereferencing to the field, i.e. like if your type was a reference type. +2. Doing a dereference on the field, for when the field itself is a reference type like `&` and `Box`. + +With `#[deref]` or `#[deref(ignore)]` it's possible to indicate the field that +you want to derive `Deref` for. + + + + +## Example usage + +```rust +# use derive_more::Deref; +# +#[derive(Deref)] +struct Num { + num: i32, +} + +#[derive(Deref)] +#[deref(forward)] +struct MyBoxedInt(Box<i32>); + +// You can specify the field you want to derive `Deref` for. +#[derive(Deref)] +struct CoolVec { + cool: bool, + #[deref] + vec: Vec<i32>, +} + +let num = Num{num: 123}; +let boxed = MyBoxedInt(Box::new(123)); +let cool_vec = CoolVec{cool: true, vec: vec![123]}; +assert_eq!(123, *num); +assert_eq!(123, *boxed); +assert_eq!(vec![123], *cool_vec); +``` + + + + +## Structs + +When deriving a non-forwarded `Deref` for a struct: + +```rust +# use derive_more::Deref; +# +#[derive(Deref)] +struct CoolVec { + cool: bool, + #[deref] + vec: Vec<i32>, +} +``` + +Code like this will be generated: + +```rust +# struct CoolVec { +# cool: bool, +# vec: Vec<i32>, +# } +impl ::core::ops::Deref for CoolVec { + type Target = Vec<i32>; + #[inline] + fn deref(&self) -> &Self::Target { + &self.vec + } +} +``` + +When deriving a forwarded `Deref` for a struct: + +```rust +# use derive_more::Deref; +# +#[derive(Deref)] +#[deref(forward)] +struct MyBoxedInt(Box<i32>); +``` + +Code like this will be generated: + +```rust +# struct MyBoxedInt(Box<i32>); +impl ::core::ops::Deref for MyBoxedInt { + type Target = <Box<i32> as ::core::ops::Deref>::Target; + #[inline] + fn deref(&self) -> &Self::Target { + <Box<i32> as ::core::ops::Deref>::deref(&self.0) + } +} +``` + + + + +## Enums + +Deriving `Deref` is not supported for enums. diff --git a/third_party/rust/derive_more-impl/doc/deref_mut.md b/third_party/rust/derive_more-impl/doc/deref_mut.md new file mode 100644 index 0000000000..8cde33d0dd --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/deref_mut.md @@ -0,0 +1,130 @@ +# What `#[derive(DerefMut)]` generates + +Deriving `Deref` only works for a single field of a struct. +Furthermore it requires that the type also implements `Deref`, so usually +`Deref` should also be derived. +The resulting implementation of `Deref` will allow you to mutably dereference +the struct its member directly. + +1. Dereferencing to the field, i.e. like if your type was a reference type. +2. Doing a dereference on the field, for when the field itself is a reference + type like `&mut` and `Box`. + +With `#[deref_mut]` or `#[deref_mut(ignore)]` it's possible to indicate the +field that you want to derive `DerefMut` for. + + + + +## Example usage + +```rust +# use derive_more::{Deref, DerefMut}; +# +#[derive(Deref, DerefMut)] +struct Num { + num: i32, +} + +#[derive(Deref, DerefMut)] +#[deref(forward)] +#[deref_mut(forward)] +struct MyBoxedInt(Box<i32>); + +// You can specify the field you want to derive DerefMut for +#[derive(Deref, DerefMut)] +struct CoolVec { + cool: bool, + #[deref] + #[deref_mut] + vec: Vec<i32>, +} + +let mut num = Num{num: 123}; +let mut boxed = MyBoxedInt(Box::new(123)); +let mut cool_vec = CoolVec{cool: true, vec: vec![123]}; +*num += 123; +assert_eq!(246, *num); +*boxed += 1000; +assert_eq!(1123, *boxed); +cool_vec.push(456); +assert_eq!(vec![123, 456], *cool_vec); +``` + + + + +## Structs + +When deriving a non-forwarded `Deref` for a struct: + +```rust +# use derive_more::{Deref, DerefMut}; +# +#[derive(Deref, DerefMut)] +struct CoolVec { + cool: bool, + #[deref] + #[deref_mut] + vec: Vec<i32>, +} +``` + +Code like this will be generated: + +```rust +# struct CoolVec { +# cool: bool, +# vec: Vec<i32>, +# } +# impl ::core::ops::Deref for CoolVec { +# type Target = Vec<i32>; +# #[inline] +# fn deref(&self) -> &Self::Target { +# &self.vec +# } +# } +impl ::core::ops::DerefMut for CoolVec { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.vec + } +} +``` + +When deriving `DerefMut` for a tuple struct with one field: + +```rust +# use derive_more::{Deref, DerefMut}; +# +#[derive(Deref, DerefMut)] +#[deref(forward)] +#[deref_mut(forward)] +struct MyBoxedInt(Box<i32>); +``` + +When deriving a forwarded `DerefMut` for a struct: + +```rust +# struct MyBoxedInt(Box<i32>); +# impl ::core::ops::Deref for MyBoxedInt { +# type Target = <Box<i32> as ::core::ops::Deref>::Target; +# #[inline] +# fn deref(&self) -> &Self::Target { +# <Box<i32> as ::core::ops::Deref>::deref(&self.0) +# } +# } +impl ::core::ops::DerefMut for MyBoxedInt { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + <Box<i32> as ::core::ops::DerefMut>::deref_mut(&mut self.0) + } +} +``` + + + + +## Enums + +Deriving `DerefMut` is not supported for enums. diff --git a/third_party/rust/derive_more-impl/doc/display.md b/third_party/rust/derive_more-impl/doc/display.md new file mode 100644 index 0000000000..5b616ca4d2 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/display.md @@ -0,0 +1,182 @@ +# What `#[derive(Display)]` generates + +Deriving `Display` will generate a `Display` implementation, with a `fmt` +method that matches `self` and each of its variants. In the case of a struct or union, +only a single variant is available, and it is thus equivalent to a simple `let` statement. +In the case of an enum, each of its variants is matched. + +For each matched variant, a `write!` expression will be generated with +the supplied format, or an automatically inferred one. + +You specify the format on each variant by writing e.g. `#[display("my val: {}", some_val * 2)]`. +For enums, you can either specify it on each variant, or on the enum as a whole. + +For variants that don't have a format specified, it will simply defer to the format of the +inner variable. If there is no such variable, or there is more than 1, an error is generated. + + + + +## The format of the format + +You supply a format by attaching an attribute of the syntax: `#[display("...", args...)]`. +The format supplied is passed verbatim to `write!`. The arguments supplied handled specially, +due to constraints in the syntax of attributes. In the case of an argument being a simple +identifier, it is passed verbatim. If an argument is a string, it is **parsed as an expression**, +and then passed to `write!`. + +The variables available in the arguments is `self` and each member of the variant, +with members of tuple structs being named with a leading underscore and their index, +i.e. `_0`, `_1`, `_2`, etc. + + +### Other formatting traits + +The syntax does not change, but the name of the attribute is the snake case version of the trait. +E.g. `Octal` -> `octal`, `Pointer` -> `pointer`, `UpperHex` -> `upper_hex`. + +Note, that `Debug` has a slightly different API and semantics, described in its docs, and so, +requires a separate `debug` feature. + + +### Generic data types + +When deriving `Display` (or other formatting trait) for a generic struct/enum, all generic type +arguments used during formatting are bound by respective formatting trait. + +E.g., for a structure `Foo` defined like this: +```rust +# use derive_more::Display; +# +# trait Trait { type Type; } +# +#[derive(Display)] +#[display("{} {} {:?} {:p}", a, b, c, d)] +struct Foo<'a, T1, T2: Trait, T3> { + a: T1, + b: <T2 as Trait>::Type, + c: Vec<T3>, + d: &'a T1, +} +``` + +The following where clauses would be generated: +* `T1: Display + Pointer` +* `<T2 as Trait>::Type: Debug` +* `Bar<T3>: Display` + + +### Custom trait bounds + +Sometimes you may want to specify additional trait bounds on your generic type parameters, so that they +could be used during formatting. This can be done with a `#[display(bound(...))]` attribute. + +`#[display(bound(...))]` accepts code tokens in a format similar to the format +used in angle bracket list (or `where` clause predicates): `T: MyTrait, U: Trait1 + Trait2`. + +Only type parameters defined on a struct allowed to appear in bound-string and they can only be bound +by traits, i.e. no lifetime parameters or lifetime bounds allowed in bound-string. + +`#[display("fmt", ...)]` arguments are parsed as an arbitrary Rust expression and passed to generated +`write!` as-is, it's impossible to meaningfully infer any kind of trait bounds for generic type parameters +used this way. That means that you'll **have to** explicitly specify all trait bound used. Either in the +struct/enum definition, or via `#[display(bound(...))]` attribute. + +Note how we have to bound `U` and `V` by `Display` in the following example, as no bound is inferred. +Not even `Display`. + +```rust +# use derive_more::Display; +# +# trait MyTrait { fn my_function(&self) -> i32; } +# +#[derive(Display)] +#[display(bound(T: MyTrait, U: Display))] +#[display("{} {} {}", a.my_function(), b.to_string().len(), c)] +struct MyStruct<T, U, V> { + a: T, + b: U, + c: V, +} +``` + + + + +## Example usage + +```rust +# use std::path::PathBuf; +# +# use derive_more::{Display, Octal, UpperHex}; +# +#[derive(Display)] +struct MyInt(i32); + +#[derive(Display)] +#[display("({x}, {y})")] +struct Point2D { + x: i32, + y: i32, +} + +#[derive(Display)] +enum E { + Uint(u32), + #[display("I am B {:b}", i)] + Binary { + i: i8, + }, + #[display("I am C {}", _0.display())] + Path(PathBuf), +} + +#[derive(Display)] +#[display("Hello there!")] +union U { + i: u32, +} + +#[derive(Octal)] +#[octal("7")] +struct S; + +#[derive(UpperHex)] +#[upper_hex("UpperHex")] +struct UH; + +#[derive(Display)] +struct Unit; + +#[derive(Display)] +struct UnitStruct {} + +#[derive(Display)] +#[display("{}", self.sign())] +struct PositiveOrNegative { + x: i32, +} + +impl PositiveOrNegative { + fn sign(&self) -> &str { + if self.x >= 0 { + "Positive" + } else { + "Negative" + } + } +} + +assert_eq!(MyInt(-2).to_string(), "-2"); +assert_eq!(Point2D { x: 3, y: 4 }.to_string(), "(3, 4)"); +assert_eq!(E::Uint(2).to_string(), "2"); +assert_eq!(E::Binary { i: -2 }.to_string(), "I am B 11111110"); +assert_eq!(E::Path("abc".into()).to_string(), "I am C abc"); +assert_eq!(U { i: 2 }.to_string(), "Hello there!"); +assert_eq!(format!("{:o}", S), "7"); +assert_eq!(format!("{:X}", UH), "UpperHex"); +assert_eq!(Unit.to_string(), "Unit"); +assert_eq!(UnitStruct {}.to_string(), "UnitStruct"); +assert_eq!(PositiveOrNegative { x: 1 }.to_string(), "Positive"); +assert_eq!(PositiveOrNegative { x: -1 }.to_string(), "Negative"); +``` diff --git a/third_party/rust/derive_more-impl/doc/error.md b/third_party/rust/derive_more-impl/doc/error.md new file mode 100644 index 0000000000..20ff24cfe4 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/error.md @@ -0,0 +1,150 @@ +# Using `#[derive(Error)]` + +Deriving `Error` will generate an `Error` implementation, that contains +(depending on the type) a `source()` and a `provide()` method. Please note, +at the time of writing `provide()` is only supported on nightly rust. So you +have to use that to make use of it. + +For a struct, these methods always do the same. For an `enum` they have separate +behaviour for each of the variants. The variant is first matched and then the +implementation will do the same as it would have done if the variant was a +struct. + +Usually when you derive `Error` you will also want to [derive `Display`](crate::Display) and +often [`From` as well](crate::From). + + +### When and how does it derive `source()`? + +1. It's a struct/variant with named fields and one is the fields is + called `source`. Then it would return that field as the `source`. +2. It's a tuple struct/variant and there's exactly one field that is not used as + the `backtrace`. So either a tuple struct with one field, or one with two where one + is the `backtrace`. Then it returns this field as the `source`. +3. One of the fields is annotated with `#[error(source)]`. Then it would + return that field as the `source`. + +### When and how does it derive `provide()`? + +1. It's a struct/variant with named fields and one of the fields is + called `backtrace`. Then it would return that field as the `backtrace`. +2. It's a tuple struct/variant and the type of exactly one of the fields is + called `Backtrace`. Then it would return that field as the `backtrace`. +3. One of the fields is annotated with `#[error(backtrace)]`. Then it would + return that field as the `backtrace`. + +### Ignoring fields for derives + +It's possible to ignore a field or a whole enum variant completely for this +derive using the `#[error(ignore)]` attribute. This will ignore it both for +detecting `backtrace` and `source`. It's also possible to mark a field only +ignored for one of these methods by using `#[error(not(backtrace))]` or +`#[error(not(source))]`. + + +### What works in `no_std`? + +If you want to use the `Error` derive on `no_std` environments, then you need to +compile with nightly and enable this feature: +```ignore +#![feature(error_in_core)] +``` + +Backtraces don't work though, because the `Backtrace` type is only available in +`std`. + + + + +## Example usage + +```rust +# #![cfg_attr(nightly, feature(error_generic_member_access, provide_any))] +// Nightly requires enabling these features: +// #![feature(error_generic_member_access, provide_any)] +# #[cfg(not(nightly))] fn main() {} +# #[cfg(nightly)] fn main() { +# use std::{any, error::Error as _, backtrace::Backtrace}; +# +# use derive_more::{Display, Error, From}; + +// std::error::Error requires std::fmt::Debug and std::fmt::Display, +// so we can also use derive_more::Display for fully declarative +// error-type definitions. + +#[derive(Default, Debug, Display, Error)] +struct Simple; + +#[derive(Default, Debug, Display, Error)] +struct WithSource { + source: Simple, +} +#[derive(Default, Debug, Display, Error)] +struct WithExplicitSource { + #[error(source)] + explicit_source: Simple, +} + +#[derive(Default, Debug, Display, Error)] +struct Tuple(Simple); + +#[derive(Default, Debug, Display, Error)] +struct WithoutSource(#[error(not(source))] i32); + +#[derive(Debug, Display, Error)] +#[display("An error with a backtrace")] +struct WithSourceAndBacktrace { + source: Simple, + backtrace: Backtrace, +} + +// derive_more::From fits nicely into this pattern as well +#[derive(Debug, Display, Error, From)] +enum CompoundError { + Simple, + WithSource { + source: Simple, + }, + #[from(ignore)] + WithBacktraceFromSource { + #[error(backtrace)] + source: Simple, + }, + #[display("{source}")] + WithDifferentBacktrace { + source: Simple, + backtrace: Backtrace, + }, + WithExplicitSource { + #[error(source)] + explicit_source: WithSource, + }, + #[from(ignore)] + WithBacktraceFromExplicitSource { + #[error(backtrace, source)] + explicit_source: WithSource, + }, + Tuple(WithExplicitSource), + WithoutSource(#[error(not(source))] Tuple), +} + +assert!(Simple.source().is_none()); +assert!(any::request_ref::<Backtrace>(&Simple).is_none()); +assert!(WithSource::default().source().is_some()); +assert!(WithExplicitSource::default().source().is_some()); +assert!(Tuple::default().source().is_some()); +assert!(WithoutSource::default().source().is_none()); +let with_source_and_backtrace = WithSourceAndBacktrace { + source: Simple, + backtrace: Backtrace::capture(), +}; +assert!(with_source_and_backtrace.source().is_some()); +assert!(any::request_ref::<Backtrace>(&with_source_and_backtrace).is_some()); + +assert!(CompoundError::Simple.source().is_none()); +assert!(CompoundError::from(Simple).source().is_some()); +assert!(CompoundError::from(WithSource::default()).source().is_some()); +assert!(CompoundError::from(WithExplicitSource::default()).source().is_some()); +assert!(CompoundError::from(Tuple::default()).source().is_none()); +# } +``` diff --git a/third_party/rust/derive_more-impl/doc/from.md b/third_party/rust/derive_more-impl/doc/from.md new file mode 100644 index 0000000000..1bc0cb4de3 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/from.md @@ -0,0 +1,188 @@ +# What `#[derive(From)]` generates + +The point of deriving this type is that it makes it easy to create a new +instance of the type by using the `.into()` method on the value(s) that it +should contain. This is done by implementing the `From` trait for the type +that is passed to the derive. + + + + +## Structs + +For structs with a single field you can call `.into()` on the desired content +itself after deriving `From`. + +```rust +# use derive_more::From; +# +#[derive(Debug, From, PartialEq)] +struct Int(i32); + +assert_eq!(Int(2), 2.into()); +``` + +For structs that have multiple fields `.into()` needs to be called on a tuple +containing the desired content for each field. + +```rust +# use derive_more::From; +# +#[derive(Debug, From, PartialEq)] +struct Point(i32, i32); + +assert_eq!(Point(1, 2), (1, 2).into()); +``` + +To specify concrete types to derive convert from use `#[from(<types>)]`. + +```rust +# use std::borrow::Cow; +# +# use derive_more::From; +# +#[derive(Debug, From, PartialEq)] +#[from(Cow<'static, str>, String, &'static str)] +struct Str(Cow<'static, str>); + +assert_eq!(Str("&str".into()), "&str".into()); +assert_eq!(Str("String".into()), "String".to_owned().into()); +assert_eq!(Str("Cow".into()), Cow::Borrowed("Cow").to_owned().into()); + +#[derive(Debug, From, PartialEq)] +#[from((i16, i16), (i32, i32))] +struct Point { + x: i32, + y: i32, +} + +assert_eq!(Point { x: 1_i32, y: 2_i32 }, (1_i16, 2_i16).into()); +assert_eq!(Point { x: 3_i32, y: 4_i32 }, (3_i32, 4_i32).into()); +``` + +Also, you can forward implementation to the inner type, which means deriving `From` for any type, that derives `From` +inner type. + +```rust +# use std::borrow::Cow; +# +# use derive_more::From; +# +#[derive(Debug, From, PartialEq)] +#[from(forward)] +struct Str { + inner: Cow<'static, str>, +} + +assert_eq!(Str { inner: "&str".into() }, "&str".into()); +assert_eq!(Str { inner: "String".into() }, "String".to_owned().into()); +assert_eq!(Str { inner: "Cow".into() }, Cow::Borrowed("Cow").to_owned().into()); +``` + + + + +## Enums + +For enums `.into()` works for each variant as if they were structs. This +includes specifying concrete types via `#[from(<types>)]` or forwarding +implementation with `#[from(forward)]`. + +```rust +# use derive_more::From; +# +#[derive(Debug, From, PartialEq)] +enum IntOrPoint { + Int(i32), + Point { + x: i32, + y: i32, + }, +} + +assert_eq!(IntOrPoint::Int(1), 1.into()); +assert_eq!(IntOrPoint::Point { x: 1, y: 2 }, (1, 2).into()); +``` + +By default, `From` is generated for every enum variant, but you can skip some +variants via `#[from(skip)]` or only concrete fields via `#[from]`. + +```rust +# mod from { +# use derive_more::From; +#[derive(Debug, From, PartialEq)] +enum Int { + #[from] + Derived(i32), + NotDerived(i32), +} +# } + +// Is equivalent to: + +# mod skip { +# use derive_more::From; +#[derive(Debug, From, PartialEq)] +enum Int { + Derived(i32), + #[from(skip)] + NotDerived(i32), +} +# } +``` + + + + +## Example usage + +```rust +# use derive_more::From; +# +// Allow converting from i32 +#[derive(From, PartialEq)] +struct MyInt(i32); + +// Forward from call to the field, so allow converting +// from anything that can be converted into an i64 (so most integers) +#[derive(From, PartialEq)] +#[from(forward)] +struct MyInt64(i64); + +// You can ignore a variant +#[derive(From, PartialEq)] +enum MyEnum { + SmallInt(i32), + NamedBigInt { int: i64 }, + #[from(ignore)] + NoFromImpl(i64), +} + +// Or explicitly annotate the ones you need +#[derive(From, PartialEq)] +enum MyEnum2 { + #[from] + SmallInt(i32), + #[from] + NamedBigInt { int: i64 }, + NoFromImpl(i64), +} + +// And even specify additional conversions for them +#[derive(From, PartialEq)] +enum MyEnum3 { + #[from(i8, i32)] + SmallInt(i32), + #[from(i16, i64)] + NamedBigInt { int: i64 }, + NoFromImpl(i64), +} + +assert!(MyInt(2) == 2.into()); +assert!(MyInt64(6) == 6u8.into()); +assert!(MyEnum::SmallInt(123) == 123i32.into()); +assert!(MyEnum::SmallInt(123) != 123i64.into()); +assert!(MyEnum::NamedBigInt{int: 123} == 123i64.into()); +assert!(MyEnum3::SmallInt(123) == 123i8.into()); +assert!(MyEnum3::NamedBigInt{int: 123} == 123i16.into()); +``` diff --git a/third_party/rust/derive_more-impl/doc/from_str.md b/third_party/rust/derive_more-impl/doc/from_str.md new file mode 100644 index 0000000000..d888e825db --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/from_str.md @@ -0,0 +1,135 @@ +# What `#[derive(FromStr)]` generates + +Deriving `FromStr` only works for enums with no fields +or newtypes, i.e structs with only a single +field. The result is that you will be able to call the `parse()` method on a +string to convert it to your newtype. This only works when the type that is +contained in the type implements `FromStr`. + + + + +## Example usage + +```rust +# use derive_more::FromStr; +# +#[derive(FromStr, Debug, Eq, PartialEq)] +struct MyInt(i32); + +#[derive(FromStr, Debug, Eq, PartialEq)] +struct Point1D{ + x: i32, +} + +assert_eq!(MyInt(5), "5".parse().unwrap()); +assert_eq!(Point1D{x: 100}, "100".parse().unwrap()); +``` + + + + +## Tuple structs + +When deriving `FromStr` for a tuple struct with one field: + +```rust +# use derive_more::FromStr; +# +#[derive(FromStr)] +struct MyInt(i32); +``` + +Code like this will be generated: + +```rust +# struct MyInt(i32); +impl ::core::str::FromStr for MyInt { + type Err = <i32 as ::core::str::FromStr>::Err; + fn from_str(src: &str) -> Result<Self, Self::Err> { + return Ok(MyInt(i32::from_str(src)?)); + } +} +``` + + + + +## Regular structs + +When deriving `FromStr` for a regular struct with one field: + +```rust +# use derive_more::FromStr; +# +#[derive(FromStr)] +struct Point1D { + x: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point1D { +# x: i32, +# } +impl ::core::str::FromStr for Point1D { + type Err = <i32 as ::core::str::FromStr>::Err; + fn from_str(src: &str) -> Result<Self, Self::Err> { + return Ok(Point1D { + x: i32::from_str(src)?, + }); + } +} +``` + + + + +## Enums + +When deriving `FromStr` for an enums with variants with no fields it will +generate a `from_str` method that converts strings that match the variant name +to the variant. If using a case insensitive match would give a unique variant +(i.e you dont have both a `MyEnum::Foo` and a `MyEnum::foo` variant) then case +insensitive matching will be used, otherwise it will fall back to exact string +matching. + +Since the string may not match any variants an error type is needed, so the +`derive_more::FromStrError` will be used for that purpose. + +e.g. Given the following enum: + +```rust +# use derive_more::FromStr; +# +#[derive(FromStr)] +enum EnumNoFields { + Foo, + Bar, + Baz, +} +``` + +Code like this will be generated: + +```rust +# enum EnumNoFields { +# Foo, +# Bar, +# Baz, +# } +# +impl ::core::str::FromStr for EnumNoFields { + type Err = ::derive_more::FromStrError; + fn from_str(src: &str) -> Result<Self, Self::Err> { + Ok(match src.to_lowercase().as_str() { + "foo" => EnumNoFields::Foo, + "bar" => EnumNoFields::Bar, + "baz" => EnumNoFields::Baz, + _ => return Err(::derive_more::FromStrError::new("EnumNoFields")), + }) + } +} +``` diff --git a/third_party/rust/derive_more-impl/doc/index.md b/third_party/rust/derive_more-impl/doc/index.md new file mode 100644 index 0000000000..c45fb46df5 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/index.md @@ -0,0 +1,74 @@ +# What `#[derive(Index)]` generates + +Deriving `Index` only works for a single field of a struct. +The result is that you will index it's member directly. + +With `#[index]` or `#[index(ignore)]` it's possible to indicate the field that +you want to derive `Index` for. + + + + +## Example usage + +```rust +# use derive_more::Index; +# +#[derive(Index)] +struct MyVec(Vec<i32>); + +// You can specify the field you want to derive Index for +#[derive(Index)] +struct Numbers { + #[index] + numbers: Vec<i32>, + useless: bool, +} + +assert_eq!(5, MyVec(vec![5, 8])[0]); +assert_eq!(200, Numbers { numbers: vec![100, 200], useless: false }[1]); +``` + + + + +## Structs + +When deriving `Index` for a struct: + +```rust +# use derive_more::Index; +# +#[derive(Index)] +struct Numbers { + #[index] + numbers: Vec<i32>, + useless: bool, +} +``` + +Code like this will be generated: + +```rust +# struct Numbers { +# numbers: Vec<i32>, +# useless: bool, +# } +impl<__IdxT> ::core::ops::Index<__IdxT> for Numbers +where + Vec<i32>: ::core::ops::Index<__IdxT>, +{ + type Output = <Vec<i32> as ::core::ops::Index<__IdxT>>::Output; + #[inline] + fn index(&self, idx: __IdxT) -> &Self::Output { + <Vec<i32> as ::core::ops::Index<__IdxT>>::index(&self.numbers, idx) + } +} +``` + + + + +## Enums + +Deriving `Index` is not supported for enums. diff --git a/third_party/rust/derive_more-impl/doc/index_mut.md b/third_party/rust/derive_more-impl/doc/index_mut.md new file mode 100644 index 0000000000..ff2347796e --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/index_mut.md @@ -0,0 +1,91 @@ +# What `#[derive(IndexMut)]` generates + +Deriving `IndexMut` only works for a single field of a struct. +Furthermore it requires that the type also implements `Index`, so usually +`Index` should also be derived. +The result is that you will mutably index it's member directly. + +With `#[index_mut]` or `#[index_mut(ignore)]` it's possible to indicate the +field that you want to derive `IndexMut` for. + + + + +## Example usage + +```rust +# use derive_more::{Index, IndexMut}; +# +#[derive(Index, IndexMut)] +struct MyVec(Vec<i32>); + +#[derive(Index, IndexMut)] +struct Numbers { + #[index] + #[index_mut] + numbers: Vec<i32>, + useless: bool, +} + +let mut myvec = MyVec(vec![5, 8]); +myvec[0] = 50; +assert_eq!(50, myvec[0]); + +let mut numbers = Numbers{numbers: vec![100, 200], useless: false}; +numbers[1] = 400; +assert_eq!(400, numbers[1]); +``` + + + + +## Regular structs + +When deriving `IndexMut` for a struct: + +```rust +# use derive_more::{Index, IndexMut}; +# +#[derive(Index, IndexMut)] +struct Numbers { + #[index] + #[index_mut] + numbers: Vec<i32>, + useless: bool, +} +``` + +Code like this will be generated to implement `IndexMut`: + +```rust +# struct Numbers { +# numbers: Vec<i32>, +# useless: bool, +# } +# impl<__IdxT> ::core::ops::Index<__IdxT> for Numbers +# where +# Vec<i32>: ::core::ops::Index<__IdxT>, +# { +# type Output = <Vec<i32> as ::core::ops::Index<__IdxT>>::Output; +# #[inline] +# fn index(&self, idx: __IdxT) -> &Self::Output { +# <Vec<i32> as ::core::ops::Index<__IdxT>>::index(&self.numbers, idx) +# } +# } +impl<__IdxT> ::core::ops::IndexMut<__IdxT> for Numbers +where + Vec<i32>: ::core::ops::IndexMut<__IdxT>, +{ + #[inline] + fn index_mut(&mut self, idx: __IdxT) -> &mut Self::Output { + <Vec<i32> as ::core::ops::IndexMut<__IdxT>>::index_mut(&mut self.numbers, idx) + } +} +``` + + + + +## Enums + +Deriving `IndexMut` is not supported for enums. diff --git a/third_party/rust/derive_more-impl/doc/into.md b/third_party/rust/derive_more-impl/doc/into.md new file mode 100644 index 0000000000..0ca676d9b3 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/into.md @@ -0,0 +1,119 @@ +# What `#[derive(Into)]` generates + +This derive creates the exact opposite of `#[derive(From)]`. +Instead of allowing you to create a new instance of the struct from the values +it should contain, it allows you to extract the values from the struct. One +thing to note is that this derive doesn't actually generate an implementation +for the `Into` trait. Instead, it derives `From` for the values contained in +the struct and thus has an indirect implementation of `Into` as +[recommended by the docs][1]. + + + + +## Structs + +For structs with a single field you can call `.into()` to extract the inner type. + +```rust +# use derive_more::Into; +# +#[derive(Debug, Into, PartialEq)] +struct Int(i32); + +assert_eq!(2, Int(2).into()); +``` + +For structs having multiple fields, `.into()` extracts a tuple containing the +desired content for each field. + +```rust +# use derive_more::Into; +# +#[derive(Debug, Into, PartialEq)] +struct Point(i32, i32); + +assert_eq!((1, 2), Point(1, 2).into()); +``` + +To specify concrete types for deriving conversions into, use `#[into(<types>)]`. + +```rust +# use std::borrow::Cow; +# +# use derive_more::Into; +# +#[derive(Debug, Into, PartialEq)] +#[into(Cow<'static, str>, String)] +struct Str(Cow<'static, str>); + +assert_eq!("String".to_owned(), String::from(Str("String".into()))); +assert_eq!(Cow::Borrowed("Cow"), <Cow<_>>::from(Str("Cow".into()))); + +#[derive(Debug, Into, PartialEq)] +#[into((i64, i64), (i32, i32))] +struct Point { + x: i32, + y: i32, +} + +assert_eq!((1_i64, 2_i64), Point { x: 1_i32, y: 2_i32 }.into()); +assert_eq!((3_i32, 4_i32), Point { x: 3_i32, y: 4_i32 }.into()); +``` + +In addition to converting to owned types, this macro supports deriving into +reference (mutable or not) via `#[into(ref(...))]`/`#[into(ref_mut(...))]`. + +```rust +# use derive_more::Into; +# +#[derive(Debug, Into, PartialEq)] +#[into(owned, ref(i32), ref_mut)] +struct Int(i32); + +assert_eq!(2, Int(2).into()); +assert_eq!(&2, <&i32>::from(&Int(2))); +assert_eq!(&mut 2, <&mut i32>::from(&mut Int(2))); +``` + +In case there are fields, that shouldn't be included in the conversion, use the +`#[into(skip)]` attribute. + +```rust +# use std::marker::PhantomData; +# +# use derive_more::Into; +# +# struct Gram; +# +#[derive(Debug, Into, PartialEq)] +#[into(i32, i64, i128)] +struct Mass<Unit> { + value: i32, + #[into(skip)] + _unit: PhantomData<Unit>, +} + +assert_eq!(5, Mass::<Gram>::new(5).into()); +assert_eq!(5_i64, Mass::<Gram>::new(5).into()); +assert_eq!(5_i128, Mass::<Gram>::new(5).into()); +# +# impl<Unit> Mass<Unit> { +# fn new(value: i32) -> Self { +# Self { +# value, +# _unit: PhantomData, +# } +# } +# } +``` + +## Enums + +Deriving `Into` for enums is not supported as it would not always be successful, +so `TryInto` should be used instead. + + + + +[1]: https://doc.rust-lang.org/core/convert/trait.Into.html diff --git a/third_party/rust/derive_more-impl/doc/into_iterator.md b/third_party/rust/derive_more-impl/doc/into_iterator.md new file mode 100644 index 0000000000..c9abe66c28 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/into_iterator.md @@ -0,0 +1,101 @@ +# Using `#[derive(IntoIterator)]` + +Deriving `IntoIterator` only works for a single field of a struct. +The result is that you will call `.into_iter()` on this field directly. + +With `#[into_iterator]` or `#[into_iterator(ignore)]` it's possible to indicate +the field that you want to derive `IntoIterator` for. + +By using `#[into_iterator(owned, ref, ref_mut)]` it's possible to derive an +`IntoIterator` implementation for reference types as well. +You can pick any combination of `owned`, `ref` and `ref_mut`. +If that's not provided the default is `#[IntoIterator(owned)]`. + + + + +## Example usage + +```rust +# use derive_more::IntoIterator; +# +#[derive(IntoIterator)] +struct MyVec(Vec<i32>); + +// You can specify the field you want to derive `IntoIterator` for +#[derive(IntoIterator)] +struct Numbers { + #[into_iterator(owned, ref, ref_mut)] + numbers: Vec<i32>, + useless: bool, +} + +assert_eq!(Some(5), MyVec(vec![5, 8]).into_iter().next()); + +let mut nums = Numbers{numbers: vec![100, 200], useless: false}; +assert_eq!(Some(&100), (&nums).into_iter().next()); +assert_eq!(Some(&mut 100), (&mut nums).into_iter().next()); +assert_eq!(Some(100), nums.into_iter().next()); +``` + + + + +## Structs + +When deriving `IntoIterator` for a struct: + +```rust +# use derive_more::IntoIterator; +# +#[derive(IntoIterator)] +struct Numbers { + #[into_iterator(owned, ref, ref_mut)] + numbers: Vec<i32>, + useless: bool, +} +``` + +Code like this will be generated: + +```rust +# struct Numbers { +# numbers: Vec<i32>, +# useless: bool, +# } +impl ::core::iter::IntoIterator for Numbers { + type Item = <Vec<i32> as ::core::iter::IntoIterator>::Item; + type IntoIter = <Vec<i32> as ::core::iter::IntoIterator>::IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + <Vec<i32> as ::core::iter::IntoIterator>::into_iter(self.numbers) + } +} + +impl<'__deriveMoreLifetime> ::core::iter::IntoIterator for &'__deriveMoreLifetime Numbers { + type Item = <&'__deriveMoreLifetime Vec<i32> as ::core::iter::IntoIterator>::Item; + type IntoIter = <&'__deriveMoreLifetime Vec<i32> as ::core::iter::IntoIterator>::IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + <&'__deriveMoreLifetime Vec<i32> as ::core::iter::IntoIterator>::into_iter(&self.numbers) + } +} + +impl<'__deriveMoreLifetime> ::core::iter::IntoIterator for &'__deriveMoreLifetime mut Numbers { + type Item = <&'__deriveMoreLifetime mut Vec<i32> as ::core::iter::IntoIterator>::Item; + type IntoIter = <&'__deriveMoreLifetime mut Vec<i32> as ::core::iter::IntoIterator>::IntoIter; + #[inline] + fn into_iter(self) -> Self::IntoIter { + <&'__deriveMoreLifetime mut Vec<i32> as ::core::iter::IntoIterator>::into_iter( + &mut self.numbers, + ) + } +} +``` + + + + +## Enums + +Deriving `IntoIterator` is not supported for enums. diff --git a/third_party/rust/derive_more-impl/doc/is_variant.md b/third_party/rust/derive_more-impl/doc/is_variant.md new file mode 100644 index 0000000000..9e549dc1bd --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/is_variant.md @@ -0,0 +1,43 @@ +# What `#[derive(IsVariant)]` generates + +When an enum is decorated with `#[derive(IsVariant)]`, for each variant `foo` in +the enum, a public instance method `is_foo(&self) -> bool` is generated. If you +don't want the `is_foo` method generated for a variant you can put the +`#[is_variant(ignore)]` attribute on that variant. + + + + +## Example usage + +```rust +# use derive_more::IsVariant; +# +#[derive(IsVariant)] +enum Maybe<T> { + Just(T), + Nothing +} + +assert!(Maybe::<()>::Nothing.is_nothing()); +assert!(!Maybe::<()>::Nothing.is_just()); +``` + + +### What is generated? + +The derive in the above example code generates the following code: +```rust +# enum Maybe<T> { +# Just(T), +# Nothing +# } +impl <T> Maybe<T>{ + pub const fn is_just(&self) -> bool { + match self {Self::Just(..) => true, _ => false} + } + pub const fn is_nothing(&self) -> bool { + match self {Self::Nothing => true, _ => false} + } +} +``` diff --git a/third_party/rust/derive_more-impl/doc/mul.md b/third_party/rust/derive_more-impl/doc/mul.md new file mode 100644 index 0000000000..a1068bef0d --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/mul.md @@ -0,0 +1,148 @@ +# What `#[derive(Mul)]` generates + +Deriving `Mul` is quite different from deriving `Add`. It is not used to +multiply two structs together. Instead it will normally multiply a struct, which +can have multiple fields, with a single primitive type (e.g. a `u64`). A new +struct is then created with all the fields from the previous struct multiplied +by this other value. + +A simple way of explaining the reasoning behind this difference between `Add` +and `Mul` deriving, is looking at arithmetic on meters. +One meter can be added to one meter, to get two meters. Also, one meter times +two would be two meters, but one meter times one meter would be one square meter. +As this second case clearly requires more knowledge about the meaning of the +type in question deriving for this is not implemented. + +NOTE: In case you don't want this behaviour you can add `#[mul(forward)]` in +addition to `#[derive(Mul)]`. This will instead generate a `Mul` implementation +with the same semantics as `Add`. + + + + +## Tuple structs + +When deriving for a tuple struct with a single field (i.e. a newtype) like this: + +```rust +# use derive_more::Mul; +# +#[derive(Mul)] +struct MyInt(i32); +``` + +Code like this will be generated: + +```rust +# struct MyInt(i32); +impl<__RhsT> ::core::ops::Mul<__RhsT> for MyInt + where i32: ::core::ops::Mul<__RhsT, Output = i32> +{ + type Output = MyInt; + fn mul(self, rhs: __RhsT) -> MyInt { + MyInt(self.0.mul(rhs)) + } +} +``` + +The behaviour is slightly different for multiple fields, since the right hand +side of the multiplication now needs the `Copy` trait. +For instance when deriving for a tuple struct with two fields like this: + +```rust +# use derive_more::Mul; +# +#[derive(Mul)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl<__RhsT: ::core::marker::Copy> ::core::ops::Mul<__RhsT> for MyInts + where i32: ::core::ops::Mul<__RhsT, Output = i32> +{ + type Output = MyInts; + fn mul(self, rhs: __RhsT) -> MyInts { + MyInts(self.0.mul(rhs), self.1.mul(rhs)) + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Regular structs + +When deriving `Mul` for a regular struct with a single field like this: + +```rust +# use derive_more::Mul; +# +#[derive(Mul)] +struct Point1D { + x: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point1D { +# x: i32, +# } +impl<__RhsT> ::core::ops::Mul<__RhsT> for Point1D + where i32: ::core::ops::Mul<__RhsT, Output = i32> +{ + type Output = Point1D; + fn mul(self, rhs: __RhsT) -> Point1D { + Point1D { x: self.x.mul(rhs) } + } +} +``` + +The behaviour is again slightly different when deriving for a struct with multiple +fields, because it still needs the `Copy` as well. +For instance when deriving for a tuple struct with two fields like this: + +```rust +# use derive_more::Mul; +# +#[derive(Mul)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl<__RhsT: ::core::marker::Copy> ::core::ops::Mul<__RhsT> for Point2D + where i32: ::core::ops::Mul<__RhsT, Output = i32> +{ + type Output = Point2D; + fn mul(self, rhs: __RhsT) -> Point2D { + Point2D { + x: self.x.mul(rhs), + y: self.y.mul(rhs), + } + } +} +``` + + + + +## Enums + +Deriving `Mul` for enums is not (yet) supported, except when you use +`#[mul(forward)]`. +Although it shouldn't be impossible no effort has been put into this yet. diff --git a/third_party/rust/derive_more-impl/doc/mul_assign.md b/third_party/rust/derive_more-impl/doc/mul_assign.md new file mode 100644 index 0000000000..e5d9225ef3 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/mul_assign.md @@ -0,0 +1,92 @@ +# What `#[derive(MulAssign)]` generates + +This code is very similar to the code that is generated for `#[derive(Mul)]`. +The difference is that it mutates the existing instance instead of creating a +new one. + +You can add the `#[mul_assign(forward)]` attribute if you don't want the same +semantics as `Mul`. +This will instead generate a `MulAssign` implementation with the same semantics +as `AddAssign`. + + + + +## Tuple structs + +When deriving `MulAssign` for a tuple struct with two fields like this: + +```rust +# use derive_more::MulAssign; +# +#[derive(MulAssign)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl<__RhsT: ::core::marker::Copy> ::core::ops::MulAssign<__RhsT> for MyInts + where i32: ::core::ops::MulAssign<__RhsT> +{ + fn mul_assign(&mut self, rhs: __RhsT) { + self.0.mul_assign(rhs); + self.1.mul_assign(rhs); + } +} +``` + +The behaviour is similar with more or less fields, except for the fact that +`__RhsT` does not need to implement `Copy` when only a single field is present. + + + + +## Regular structs + +When deriving `MulAssign` for a regular struct with two fields like this: + +```rust +# use derive_more::MulAssign; +# +#[derive(MulAssign)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl<__RhsT: ::core::marker::Copy> ::core::ops::MulAssign<__RhsT> for Point2D + where i32: ::core::ops::MulAssign<__RhsT> +{ + fn mul_assign(&mut self, rhs: __RhsT) { + self.x.mul_assign(rhs); + self.y.mul_assign(rhs); + } +} +``` + +The behaviour is again similar with more or less fields, except that `Copy` +doesn't have to be implemented for `__Rhst` when the struct has only a single +field. + + + + +## Enums + +Deriving `MulAssign` for enums is not (yet) supported. +This has two reason, the first being that deriving `Mul` is also not implemented +for enums yet. +The second reason is the same as for `AddAssign`. +Even if it would be deriving `Mul` was implemented it would likely return a +`Result<EnumType>` instead of an `EnumType`. +Handling the case where it errors would be hard and maybe impossible. diff --git a/third_party/rust/derive_more-impl/doc/not.md b/third_party/rust/derive_more-impl/doc/not.md new file mode 100644 index 0000000000..9997c085ab --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/not.md @@ -0,0 +1,159 @@ +# What `#[derive(Not)]` generates + +The derived `Not` implementation simply negates all the fields of a +struct and returns that as a new instance of the struct. +For enums all fields of the active variant of the enum are negated and a new +instance of the same variant with these negated fields is returned. + + + + +## Tuple structs + +When deriving for a tuple struct with two fields like this: + +```rust +# use derive_more::Not; +# +#[derive(Not)] +struct MyInts(i32, i32); +``` + +Code like this will be generated: + +```rust +# struct MyInts(i32, i32); +impl ::core::ops::Not for MyInts { + type Output = MyInts; + fn not(self) -> MyInts { + MyInts(self.0.not(), self.1.not()) + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Regular structs + +When deriving for a regular struct with two fields like this: + +```rust +# use derive_more::Not; +# +#[derive(Not)] +struct Point2D { + x: i32, + y: i32, +} +``` + +Code like this will be generated: + +```rust +# struct Point2D { +# x: i32, +# y: i32, +# } +impl ::core::ops::Not for Point2D { + type Output = Point2D; + fn not(self) -> Point2D { + Point2D { + x: self.x.not(), + y: self.y.not(), + } + } +} +``` + +The behaviour is similar with more or less fields. + + + + +## Enums + +For each enum variant `Not` is derived in a similar way as it would be derived +if it would be its own type. +For instance when deriving `Not` for an enum like this: + +```rust +# use derive_more::Not; +# +#[derive(Not)] +enum MixedInts { + SmallInt(i32), + BigInt(i64), + TwoSmallInts(i32, i32), + NamedSmallInts { x: i32, y: i32 }, + UnsignedOne(u32), + UnsignedTwo(u32), +} +``` + +Code like this will be generated: + +```rust +# enum MixedInts { +# SmallInt(i32), +# BigInt(i64), +# TwoSmallInts(i32, i32), +# NamedSmallInts { x: i32, y: i32 }, +# UnsignedOne(u32), +# UnsignedTwo(u32), +# } +impl ::core::ops::Not for MixedInts { + type Output = MixedInts; + fn not(self) -> MixedInts { + match self { + MixedInts::SmallInt(__0) => MixedInts::SmallInt(__0.not()), + MixedInts::BigInt(__0) => MixedInts::BigInt(__0.not()), + MixedInts::TwoSmallInts(__0, __1) => MixedInts::TwoSmallInts(__0.not(), __1.not()), + MixedInts::NamedSmallInts { x: __0, y: __1 } => { + MixedInts::NamedSmallInts { + x: __0.not(), + y: __1.not(), + } + } + MixedInts::UnsignedOne(__0) => MixedInts::UnsignedOne(__0.not()), + MixedInts::UnsignedTwo(__0) => MixedInts::UnsignedTwo(__0.not()), + } + } +} +``` + +There is one important thing to remember though. +If you add a unit variant to the enum its return type will change from +`EnumType` to `Result<EnumType>`. +This is because Unit cannot have `Not` implemented. +So, when deriving `Not` for an enum like this: + +```rust +# use derive_more::Not; +# +#[derive(Not)] +enum EnumWithUnit { + SmallInt(i32), + Unit, +} +``` + +Code like this will be generated: + +```rust +# enum EnumWithUnit { +# SmallInt(i32), +# Unit, +# } +impl ::core::ops::Not for EnumWithUnit { + type Output = Result<EnumWithUnit, ::derive_more::ops::UnitError>; + fn not(self) -> Result<EnumWithUnit, ::derive_more::ops::UnitError> { + match self { + EnumWithUnit::SmallInt(__0) => Ok(EnumWithUnit::SmallInt(__0.not())), + EnumWithUnit::Unit => Err(::derive_more::ops::UnitError::new("not")), + } + } +} +``` diff --git a/third_party/rust/derive_more-impl/doc/sum.md b/third_party/rust/derive_more-impl/doc/sum.md new file mode 100644 index 0000000000..ffb5ea6be2 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/sum.md @@ -0,0 +1,77 @@ +# Using `#[derive(Sum)]` + +The derived `Sum` implementation will allow an iterator of your type to be +summed together into a new instance of the type with all the fields added +together. Apart from the original types requiring an implementation of `Sum`, it +is also required that your type to implements `Add`. So normally you want to +derive that one as well. + +All this is also true for the `Product`, except that then all the fields are +multiplied and an implementation of `Mul` is required. This is usually the +easiest to implement by adding `#[derive(MulSelf)]`. + + + + +## Example usage + +```rust +# use derive_more::{Add, Sum}; +# +#[derive(Add, Sum, PartialEq)] +struct MyInts(i32, i64); + +let int_vec = vec![MyInts(2, 3), MyInts(4, 5), MyInts(6, 7)]; +assert!(MyInts(12, 15) == int_vec.into_iter().sum()) +``` + + + + +## Structs + +When deriving `Sum` for a struct with two fields its like this: + +```rust +# use derive_more::{Add, Sum}; +# +#[derive(Add, Sum)] +struct MyInts(i32, i64); +``` + +Code like this will be generated for the `Sum` implementation: + +```rust +# struct MyInts(i32, i64); +# impl ::core::ops::Add for MyInts { +# type Output = MyInts; +# #[inline] +# fn add(self, rhs: MyInts) -> MyInts { +# MyInts(self.0.add(rhs.0), self.1.add(rhs.1)) +# } +# } +impl ::core::iter::Sum for MyInts { + #[inline] + fn sum<I: ::core::iter::Iterator<Item = Self>>(iter: I) -> Self { + iter.fold( + MyInts( + ::core::iter::empty::<i32>().sum(), + ::core::iter::empty::<i64>().sum(), + ), + ::core::ops::Add::add, + ) + } +} +``` + +The trick here is that we get the identity struct by calling sum on empty +iterators. +This way we can get the identity for sum (i.e. `0`) and the identity for product +(i.e. `1`). + + + + +## Enums + +Deriving `Sum` for enums is not supported. diff --git a/third_party/rust/derive_more-impl/doc/try_into.md b/third_party/rust/derive_more-impl/doc/try_into.md new file mode 100644 index 0000000000..252a33bf4d --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/try_into.md @@ -0,0 +1,182 @@ +# What `#[derive(TryInto)]` generates + +This derive allows you to convert enum variants into their corresponding +variant types. +One thing to note is that this derive doesn't actually generate an +implementation for the `TryInto` trait. +Instead it derives `TryFrom` for each variant in the enum and thus has an +indirect implementation of `TryInto` as recommended by the +[docs](https://doc.rust-lang.org/core/convert/trait.TryInto.html). + +By using `#[try_into(owned, ref, ref_mut)]` it's possible to derive a `TryInto` +implementation for reference types as well. +You can pick any combination of `owned`, `ref` and `ref_mut`. +If that's not provided the default is `#[try_into(owned)]`. + +With `#[try_into]` or `#[try_into(ignore)]` it's possible to indicate which +variants you want to derive `TryInto` for. + + + + +## Example usage + +```rust +# use derive_more::TryInto; +# +#[derive(TryInto, Clone, Debug)] +#[try_into(owned, ref, ref_mut)] +enum MixedData { + Int(u32), + String(String), +} + +let mixed_string = MixedData::String("foo".to_string()); +let mixed_int1 = MixedData::Int(123); +let mixed_int2 = mixed_int1.clone(); +let mut mixed_int3 = mixed_int1.clone(); + +assert_eq!(123u32, mixed_int1.try_into().unwrap()); + +let int_ref : &u32 = (&mixed_int2).try_into().unwrap(); +assert_eq!(&123u32, int_ref); + +let int_ref_mut : &mut u32 = (&mut mixed_int3).try_into().unwrap(); +assert_eq!(&mut 123u32, int_ref_mut); + +assert_eq!("foo".to_string(), String::try_from(mixed_string.clone()).unwrap()); + +assert!(u32::try_from(mixed_string).is_err()); +``` + + + + +## Structs + +Deriving `TryInto` for structs is not supported because there is no failing +mode. Use `#[derive(Into)]` instead. `TryInto` will automatically get a +blanket implementation through `TryFrom`, automatically derived from `From`, +which `#[derive(Into)]` produces. + + + + +## Enums + +When deriving `TryInto` for an enum, each enum variant gets its own +`TryFrom` implementation. +For instance, when deriving `TryInto` for an enum link this: + +```rust +# use derive_more::TryInto; +# +#[derive(TryInto)] +enum MixedInts { + SmallInt(i32), + BigInt(i64), + TwoSmallInts(i32, i32), + NamedSmallInts { x: i64, y: i64 }, + UnsignedOne(u32), + UnsignedTwo(u32), + #[try_into(ignore)] + NotImportant, +} +``` + +Code like this will be generated: + +```rust +# enum MixedInts { +# SmallInt(i32), +# BigInt(i64), +# TwoSmallInts(i32, i32), +# NamedSmallInts { x: i64, y: i64 }, +# UnsignedOne(u32), +# UnsignedTwo(u32), +# } +impl ::core::convert::TryFrom<MixedInts> for (i32) { + type Error = &'static str; + fn try_from(value: MixedInts) -> Result<Self, Self::Error> { + match value { + MixedInts::SmallInt(__0) => Ok(__0), + _ => Err("Only SmallInt can be converted to i32"), + } + } +} +impl ::core::convert::TryFrom<MixedInts> for (i64) { + type Error = &'static str; + fn try_from(value: MixedInts) -> Result<Self, Self::Error> { + match value { + MixedInts::BigInt(__0) => Ok(__0), + _ => Err("Only BigInt can be converted to i64"), + } + } +} +impl ::core::convert::TryFrom<MixedInts> for (i32, i32) { + type Error = &'static str; + fn try_from(value: MixedInts) -> Result<Self, Self::Error> { + match value { + MixedInts::TwoSmallInts(__0, __1) => Ok((__0, __1)), + _ => Err("Only TwoSmallInts can be converted to (i32, i32)"), + } + } +} +impl ::core::convert::TryFrom<MixedInts> for (i64, i64) { + type Error = &'static str; + fn try_from(value: MixedInts) -> Result<Self, Self::Error> { + match value { + MixedInts::NamedSmallInts { x: __0, y: __1 } => Ok((__0, __1)), + _ => Err("Only NamedSmallInts can be converted to (i64, i64)"), + } + } +} +impl ::core::convert::TryFrom<MixedInts> for (u32) { + type Error = &'static str; + fn try_from(value: MixedInts) -> Result<Self, Self::Error> { + match value { + MixedInts::UnsignedOne(__0) | MixedInts::UnsignedTwo(__0) => Ok(__0), + _ => Err("Only UnsignedOne, UnsignedTwo can be converted to u32"), + } + } +} +``` + +When deriving `TryInto` for an enum with Unit variants like this: + +```rust +# use derive_more::TryInto; +# +#[derive(TryInto)] +enum EnumWithUnit { + SmallInt(i32), + Unit, +} +``` + +Code like this will be generated: + +```rust +# enum EnumWithUnit { +# SmallInt(i32), +# Unit, +# } +impl ::core::convert::TryFrom<EnumWithUnit> for (i32) { + type Error = &'static str; + fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> { + match value { + EnumWithUnit::SmallInt(__0) => Ok(__0), + _ => Err("Only SmallInt can be converted to i32"), + } + } +} +impl ::core::convert::TryFrom<EnumWithUnit> for () { + type Error = &'static str; + fn try_from(value: EnumWithUnit) -> Result<Self, Self::Error> { + match value { + EnumWithUnit::Unit => Ok(()), + _ => Err("Only Unit can be converted to ()"), + } + } +} +``` diff --git a/third_party/rust/derive_more-impl/doc/try_unwrap.md b/third_party/rust/derive_more-impl/doc/try_unwrap.md new file mode 100644 index 0000000000..f6ec49ee01 --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/try_unwrap.md @@ -0,0 +1,80 @@ +# What `#[derive(TryUnwrap)]` generates + +This works almost like `Unwrap`. +When an enum is decorated with `#[derive(TryUnwrap)]`, for each variant `foo` in the enum, with fields `(a, b, c, ...)` a public instance method `try_unwrap_foo(self) -> Result<(a, b, c, ...), TryUnwrapError<Self>>` is generated. +If you don't want the `try_unwrap_foo` method generated for a variant, you can put the `#[try_unwrap(ignore)]` attribute on that variant. +If you want to treat a reference, you can put the `#[try_unwrap(ref)]` attribute on the enum declaration or that variant, then `try_unwrap_foo_ref(self) -> Result<(&a, &b, &c, ...), TryUnwrapError<&Self>>` will be generated. You can also use mutable references by putting `#[unwrap(ref_mut)]`. +However, unlike `Unwrap`, it does not panic if the conversion fails. Also, values that fail to convert are not dropped but returned as an `Err`. + +## Example usage + +```rust +# use derive_more::TryUnwrap; +# +# #[derive(Debug, PartialEq)] +#[derive(TryUnwrap)] +#[try_unwrap(ref)] +enum Maybe<T> { + Nothing, + Just(T), +} + +fn main() { + assert_eq!(Maybe::Just(1).try_unwrap_just(), Ok(1)); + + // Unlike `Unwrap`, it does not panic. + assert_eq!( + Maybe::<()>::Nothing.try_unwrap_just().map_err(|err| err.input), + Err(Maybe::<()>::Nothing), // and the value is returned! + ); + assert_eq!( + Maybe::Just(2).try_unwrap_nothing().map_err(|err| err.input), + Err(Maybe::Just(2)), + ); + assert_eq!( + Maybe::<()>::Nothing.try_unwrap_just().map_err(|err| err.to_string()), + Err("Attempt to call `Maybe::try_unwrap_just()` on a `Maybe::Nothing` value".into()), + ); + + assert_eq!((&Maybe::Just(42)).try_unwrap_just_ref(), Ok(&42)); +} +``` + +### What is generated? + +The derive in the above example code generates the following code: +```rust +# use derive_more::TryUnwrapError; +# +# enum Maybe<T> { +# Just(T), +# Nothing, +# } +# +impl<T> Maybe<T> { + pub fn try_unwrap_nothing(self) -> Result<(), TryUnwrapError<Self>> { + match self { + Maybe::Nothing => Ok(()), + val @ _ => Err(todo!("TryUnwrapError::new(val, /* omitted */)")), + } + } + pub fn try_unwrap_nothing_ref(&self) -> Result<(), TryUnwrapError<&Self>> { + match self { + Maybe::Nothing => Ok(()), + val @ _ => Err(todo!("TryUnwrapError::new(val, /* omitted */)")), + } + } + pub fn try_unwrap_just(self) -> Result<T, TryUnwrapError<Self>> { + match self { + Maybe::Just(field_0) => Ok(field_0), + val @ _ => Err(todo!("TryUnwrapError::new(val, /* omitted */)")), + } + } + pub fn try_unwrap_just_ref(&self) -> Result<&T, TryUnwrapError<&Self>> { + match self { + Maybe::Just(field_0) => Ok(field_0), + val @ _ => Err(todo!("TryUnwrapError::new(val, /* omitted */)")), + } + } +} +``` diff --git a/third_party/rust/derive_more-impl/doc/unwrap.md b/third_party/rust/derive_more-impl/doc/unwrap.md new file mode 100644 index 0000000000..e1a103476b --- /dev/null +++ b/third_party/rust/derive_more-impl/doc/unwrap.md @@ -0,0 +1,70 @@ +# What `#[derive(Unwrap)]` generates + +When an enum is decorated with `#[derive(Unwrap)]`, for each variant `foo` in the enum, with fields `(a, b, c, ...)` a public instance method `unwrap_foo(self) -> (a, b, c, ...)` is generated. +If you don't want the `unwrap_foo` method generated for a variant, you can put the `#[unwrap(ignore)]` attribute on that variant. +If you want to treat a reference, you can put the `#[unwrap(ref)]` attribute on the enum declaration or that variant, then `unwrap_foo_ref(self) -> (&a, &b, &c, ...)` will be generated. You can also use mutable references by putting `#[unwrap(ref_mut)]`. + + + + +## Example usage + +```rust +# use derive_more::Unwrap; +# +# #[derive(Debug, PartialEq)] +#[derive(Unwrap)] +#[unwrap(ref)] +enum Maybe<T> { + Just(T), + Nothing, +} + +fn main() { + assert_eq!(Maybe::Just(1).unwrap_just(), 1); + + // Panics if variants are different + // assert_eq!(Maybe::<()>::Nothing.unwrap_just(), /* panic */); + // assert_eq!(Maybe::Just(2).unwrap_nothing(), /* panic */); + + assert_eq!((&Maybe::Just(42)).unwrap_just_ref(), &42); +} +``` + + +### What is generated? + +The derive in the above example code generates the following code: +```rust +# enum Maybe<T> { +# Just(T), +# Nothing, +# } +# +impl<T> Maybe<T> { + pub fn unwrap_nothing(self) -> () { + match self { + Maybe::Nothing => (), + _ => panic!(), + } + } + pub fn unwrap_nothing_ref(&self) -> () { + match self { + Maybe::Nothing => (), + _ => panic!(), + } + } + pub fn unwrap_just(self) -> T { + match self { + Maybe::Just(field_0) => field_0, + _ => panic!(), + } + } + pub fn unwrap_just_ref(&self) -> &T { + match self { + Maybe::Just(field_0) => field_0, + _ => panic!(), + } + } +} +``` |