Bug 1716518 - Upgrade derive_more to v0.99.11. r=emilio

Latest version is v0.99.14 but it adds new dependencies.

Differential Revision: https://phabricator.services.mozilla.com/D117780
This commit is contained in:
Mike Hommey 2021-06-15 21:00:57 +00:00
Родитель fe32d4f0f5
Коммит 7b2c7f4f51
53 изменённых файлов: 5480 добавлений и 305 удалений

4
Cargo.lock сгенерированный
Просмотреть файл

@ -1136,9 +1136,9 @@ dependencies = [
[[package]]
name = "derive_more"
version = "0.99.2"
version = "0.99.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8"
checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
dependencies = [
"proc-macro2",
"quote",

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

60
third_party/rust/derive_more/CHANGELOG.md поставляемый
Просмотреть файл

@ -5,12 +5,70 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## 0.99.10 - 2020-??-??
### Improvements
- `From` supports additional types for conversion: `#[from(types(u8, u16))]`.
## 0.99.7 - 2020-05-16
### Fixes
- Fix generic derives for `MulAssign`
### Improvements
- When specifying specific features of the crate to only enable specific
derives, the `extra-traits` feature of `syn` is not always enabled
when those the specified features do not require it. This should speed up
compile time of `syn` when this feature is not needed.
## 0.99.6 - 2020-05-13
### Improvements
- Make sure output of derives is deterministic, for better support in
rust-analyzer
## 0.99.5 - 2020-03-28
### New features
- Support for deriving `Error`!!! (many thanks to @ffuugoo and @tyranron)
### Fixes
- Fix generic bounds for `Deref` and `DerefMut` with `forward`, i.e. put `Deref`
bound on whole type, so on `where Box<T>: Deref` instead of on `T: Deref`.
([#107](https://github.com/JelteF/derive_more/issues/114))
- The `tests` directory is now correctly included in the crate (requested by
Debian package maintainers)
## 0.99.4 - 2020-03-28
Note: This version is yanked, because quickly after release it was found out
tests did not run in CI.
## 0.99.3 - 2020-02-19
### Fixes
- Fix generic bounds for `Deref` and `DerefMut` with no `forward`, i.e. no bounds
are necessary. ([#107](https://github.com/JelteF/derive_more/issues/114))
## 0.99.2 - 2019-11-17
### Fixes
- Hotfix for a regression in allowed `Display` derives using `#` flag, such as
`{:#b}` ([#107](https://github.com/JelteF/derive_more/issues/105))
`{:#b}` ([#107](https://github.com/JelteF/derive_more/issues/107))
## 0.99.1 - 2019-11-12

27
third_party/rust/derive_more/Cargo.lock сгенерированный поставляемый
Просмотреть файл

@ -2,11 +2,12 @@
# It is not intended for manual editing.
[[package]]
name = "derive_more"
version = "0.99.2"
version = "0.99.11"
dependencies = [
"peg 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -39,6 +40,27 @@ dependencies = [
"proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "1.0.3"
@ -59,5 +81,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49d77c41ca8767f2f41394c11a4eebccab83da25e7cc035387a3125f02be90a3"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "158521e6f544e7e3dcfc370ac180794aa38cb34a1b1e07609376d4adcf429b93"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"

32
third_party/rust/derive_more/Cargo.toml поставляемый
Просмотреть файл

@ -13,9 +13,9 @@
[package]
edition = "2018"
name = "derive_more"
version = "0.99.2"
version = "0.99.11"
authors = ["Jelte Fennema <github-tech@jeltef.nl>"]
include = ["src/**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "test/**/*.rs"]
include = ["src/**/*.rs", "Cargo.toml", "LICENSE", "README.md", "CHANGELOG.md", "tests/**/*.rs"]
autotests = true
description = "Adds #[derive(x)] macros for more traits"
documentation = "https://jeltef.github.io/derive_more/derive_more/"
@ -79,6 +79,11 @@ name = "display"
path = "tests/display.rs"
required-features = ["display"]
[[test]]
name = "error"
path = "tests/error_tests.rs"
required-features = ["error"]
[[test]]
name = "from"
path = "tests/from.rs"
@ -156,35 +161,40 @@ version = "1"
[dependencies.syn]
version = "1"
features = ["extra-traits"]
[build-dependencies.peg]
version = "0.5"
optional = true
[build-dependencies.rustc_version]
version = "0.2"
optional = true
[features]
add = []
add_assign = []
as_mut = []
as_ref = []
constructor = []
default = ["add_assign", "add", "as_mut", "as_ref", "constructor", "deref", "deref_mut", "display", "from", "from_str", "index", "index_mut", "into", "into_iterator", "iterator", "mul_assign", "mul", "not", "sum", "try_into"]
default = ["add_assign", "add", "as_mut", "as_ref", "constructor", "deref", "deref_mut", "display", "error", "from", "from_str", "index", "index_mut", "into", "into_iterator", "iterator", "mul_assign", "mul", "not", "sum", "try_into"]
deref = []
deref_mut = []
display = []
from = []
display = ["syn/extra-traits"]
error = ["syn/extra-traits"]
from = ["syn/extra-traits"]
from_str = []
generate-parsing-rs = ["peg"]
index = []
index_mut = []
into = []
into = ["syn/extra-traits"]
into_iterator = []
iterator = []
mul = []
mul_assign = []
mul = ["syn/extra-traits"]
mul_assign = ["syn/extra-traits"]
nightly = []
not = []
not = ["syn/extra-traits"]
sum = []
try_into = []
testing-helpers = ["rustc_version"]
try_into = ["syn/extra-traits"]
[badges.github]
repository = "JelteF/derive_more"
workflow = "CI"

7
third_party/rust/derive_more/README.md поставляемый
Просмотреть файл

@ -90,6 +90,11 @@ These traits are used for converting a struct to a string in different ways.
1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
`UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
### Error-handling traits
These traits are used to define error-types.
1. [`Error`]
### Operators
These are traits that can be used for operator overloading.
@ -159,6 +164,8 @@ extern crate derive_more;
[`Display`-like]: https://jeltef.github.io/derive_more/derive_more/display.html
[`Error`]: https://jeltef.github.io/derive_more/derive_more/error.html
[`Index`]: https://jeltef.github.io/derive_more/derive_more/index_op.html
[`Deref`]: https://jeltef.github.io/derive_more/derive_more/deref.html
[`Not`-like]: https://jeltef.github.io/derive_more/derive_more/not.html

8
third_party/rust/derive_more/src/as_mut.rs поставляемый
Просмотреть файл

@ -1,15 +1,19 @@
use crate::utils::{add_where_clauses_for_new_ident, MultiFieldData, State};
use crate::utils::{
add_where_clauses_for_new_ident, AttrParams, MultiFieldData, State,
};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{parse::Result, DeriveInput, Ident};
pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
let as_mut_type = &Ident::new("__AsMutT", Span::call_site());
let state = State::with_field_ignore_and_forward(
let state = State::with_type_bound(
input,
trait_name,
quote!(::core::convert),
String::from("as_mut"),
AttrParams::ignore_and_forward(),
false,
)?;
let MultiFieldData {
fields,

12
third_party/rust/derive_more/src/as_ref.rs поставляемый
Просмотреть файл

@ -1,15 +1,19 @@
use crate::utils::{add_where_clauses_for_new_ident, MultiFieldData, State};
use crate::utils::{
add_where_clauses_for_new_ident, AttrParams, MultiFieldData, State,
};
use proc_macro2::{Span, TokenStream};
use quote::quote;
use syn::{parse::Result, DeriveInput, Ident};
pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
let as_ref_type = &Ident::new("__AsRefT", Span::call_site());
let state = State::with_field_ignore_and_forward(
let state = State::with_type_bound(
input,
trait_name,
quote!(::core::convert),
String::from("as_ref"),
AttrParams::ignore_and_forward(),
false,
)?;
let MultiFieldData {
fields,
@ -61,13 +65,13 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
})
.collect();
let bodies = sub_items.iter().map(|i| &i.0);
let impl_genericses = sub_items.iter().map(|i| &i.1);
let impl_generics = sub_items.iter().map(|i| &i.1);
let where_clauses = sub_items.iter().map(|i| &i.2);
let trait_paths = sub_items.iter().map(|i| &i.3);
let return_types = sub_items.iter().map(|i| &i.4);
Ok(quote! {#(
impl#impl_genericses #trait_paths for #input_type#ty_generics
impl#impl_generics #trait_paths for #input_type#ty_generics
#where_clauses
{
#[inline]

19
third_party/rust/derive_more/src/deref.rs поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
use crate::utils::{SingleFieldData, State};
use crate::utils::{add_extra_where_clauses, SingleFieldData, State};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse::Result, DeriveInput};
@ -16,22 +16,31 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
field_type,
trait_path,
casted_trait,
impl_generics,
ty_generics,
where_clause,
member,
info,
..
} = state.assert_single_enabled_field();
let (target, body) = if info.forward {
let (target, body, generics) = if info.forward {
(
quote!(#casted_trait::Target),
quote!(#casted_trait::deref(&#member)),
add_extra_where_clauses(
&input.generics,
quote! {
where #field_type: #trait_path
},
),
)
} else {
(quote!(#field_type), quote!(&#member))
(
quote!(#field_type),
quote!(&#member),
input.generics.clone(),
)
};
let (impl_generics, _, where_clause) = generics.split_for_impl();
Ok(quote! {
impl#impl_generics #trait_path for #input_type#ty_generics #where_clause

20
third_party/rust/derive_more/src/deref_mut.rs поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
use crate::utils::{SingleFieldData, State};
use crate::utils::{add_extra_where_clauses, SingleFieldData, State};
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse::Result, DeriveInput};
@ -15,18 +15,26 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
input_type,
trait_path,
casted_trait,
impl_generics,
ty_generics,
where_clause,
field_type,
member,
info,
..
} = state.assert_single_enabled_field();
let body = if info.forward {
quote!(#casted_trait::deref_mut(&mut #member))
let (body, generics) = if info.forward {
(
quote!(#casted_trait::deref_mut(&mut #member)),
add_extra_where_clauses(
&input.generics,
quote! {
where #field_type: #trait_path
},
),
)
} else {
quote!(&mut #member)
(quote!(&mut #member), input.generics.clone())
};
let (impl_generics, _, where_clause) = generics.split_for_impl();
Ok(quote! {
impl#impl_generics #trait_path for #input_type#ty_generics #where_clause

152
third_party/rust/derive_more/src/display.rs поставляемый
Просмотреть файл

@ -1,21 +1,15 @@
use std::{
collections::{HashMap, HashSet},
fmt::Display,
iter::FromIterator as _,
ops::Deref as _,
str::FromStr as _,
};
use std::{fmt::Display, iter::FromIterator as _, str::FromStr as _};
use crate::utils::add_extra_where_clauses;
use proc_macro2::{Ident, Span, TokenStream};
use quote::{quote, quote_spanned};
use syn::{
parse::{Error, Parser as _, Result},
punctuated::Punctuated,
spanned::Spanned as _,
parse::Parser as _, punctuated::Punctuated, spanned::Spanned as _, Error, Result,
};
/// Provides the hook to expand `#[derive(Display)]` into an implementation of `Display`
use crate::utils;
use utils::{HashMap, HashSet};
/// Provides the hook to expand `#[derive(Display)]` into an implementation of `From`
pub fn expand(input: &syn::DeriveInput, trait_name: &str) -> Result<TokenStream> {
let trait_name = trait_name.trim_end_matches("Custom");
let trait_ident = syn::Ident::new(trait_name, Span::call_site());
@ -51,7 +45,7 @@ pub fn expand(input: &syn::DeriveInput, trait_name: &str) -> Result<TokenStream>
})
.collect();
let where_clause = quote_spanned!(input.span()=> where #(#bounds),*);
add_extra_where_clauses(&input.generics, where_clause)
utils::add_extra_where_clauses(&input.generics, where_clause)
} else {
input.generics.clone()
};
@ -278,7 +272,7 @@ impl<'a, 'b> State<'a, 'b> {
return Err(Error::new(span, "No bounds specified"));
}
let mut bounds = HashMap::new();
let mut bounds = HashMap::default();
for generic_param in generic_params {
let type_param = match generic_param {
@ -303,7 +297,7 @@ impl<'a, 'b> State<'a, 'b> {
qself: None,
path: type_param.ident.into(),
});
let bounds = bounds.entry(ty).or_insert_with(HashSet::new);
let bounds = bounds.entry(ty).or_insert_with(HashSet::default);
for bound in type_param.bounds {
let bound = match bound {
@ -352,11 +346,12 @@ impl<'a, 'b> State<'a, 'b> {
op if op.segments.first().expect("path shouldn't be empty").ident
== "fmt" =>
{
let expected_affix_usage = "outer `enum` `fmt` is an affix spec that expects no args and at most 1 placeholder for inner variant display";
if outer_enum {
if list.nested.iter().skip(1).count() != 0 {
return Err(Error::new(
list.nested[1].span(),
"`fmt` formatting requires a single `fmt` argument",
expected_affix_usage,
));
}
// TODO: Check for a single `Display` group?
@ -385,7 +380,7 @@ impl<'a, 'b> State<'a, 'b> {
if num_placeholders > 1 {
return Err(Error::new(
list.nested[1].span(),
"fmt string for enum should have at at most 1 placeholder",
expected_affix_usage,
));
}
if num_placeholders == 1 {
@ -447,7 +442,7 @@ impl<'a, 'b> State<'a, 'b> {
} else if fields.len() > 1 {
return Err(Error::new(
fields.span(),
"Can not automatically infer format for types with more than 1 field",
"Cannot automatically infer format for types with more than 1 field",
));
}
@ -480,7 +475,7 @@ impl<'a, 'b> State<'a, 'b> {
Ok(ParseResult {
arms: quote_spanned!(self.input.span()=> _ => #fmt,),
bounds: HashMap::new(),
bounds: HashMap::default(),
requires_helper: false,
})
}
@ -504,7 +499,7 @@ impl<'a, 'b> State<'a, 'b> {
let fmt = fmt?;
Ok(ParseResult {
arms: quote_spanned!(self.input.span()=> #fmt),
bounds: HashMap::new(),
bounds: HashMap::default(),
requires_helper: true,
})
}
@ -558,14 +553,14 @@ impl<'a, 'b> State<'a, 'b> {
self.find_meta(&self.input.attrs, "fmt")?.ok_or_else(|| {
Error::new(
self.input.span(),
"Can not automatically infer format for unions",
"Cannot automatically infer format for unions",
)
})?;
let fmt = self.parse_meta_fmt(&meta, false)?.0;
Ok(ParseResult {
arms: quote_spanned!(self.input.span()=> _ => #fmt,),
bounds: HashMap::new(),
bounds: HashMap::default(),
requires_helper: false,
})
}
@ -613,29 +608,30 @@ impl<'a, 'b> State<'a, 'b> {
meta: &syn::Meta,
) -> HashMap<syn::Type, HashSet<syn::TraitBound>> {
if self.type_params.is_empty() {
return HashMap::new();
return HashMap::default();
}
let fields_type_params: HashMap<syn::Path, _> = fields
.iter()
.enumerate()
.filter_map(|(i, field)| {
self.get_type_param(&field.ty).map(|ty| {
(
field
.ident
.clone()
.unwrap_or_else(|| {
Ident::new(&format!("_{}", i), Span::call_site())
})
.into(),
ty,
)
})
utils::get_if_type_parameter_used_in_type(&self.type_params, &field.ty)
.map(|ty| {
(
field
.ident
.clone()
.unwrap_or_else(|| {
Ident::new(&format!("_{}", i), Span::call_site())
})
.into(),
ty,
)
})
})
.collect();
if fields_type_params.is_empty() {
return HashMap::new();
return HashMap::default();
}
let list = match meta {
@ -658,7 +654,7 @@ impl<'a, 'b> State<'a, 'b> {
})
.collect();
if fmt_args.is_empty() {
return HashMap::new();
return HashMap::default();
}
let fmt_string = match &list.nested[0] {
syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue {
@ -679,13 +675,13 @@ impl<'a, 'b> State<'a, 'b> {
};
Placeholder::parse_fmt_string(&fmt_string).into_iter().fold(
HashMap::new(),
HashMap::default(),
|mut bounds, pl| {
if let Some(arg) = fmt_args.get(&pl.position) {
if fields_type_params.contains_key(arg) {
bounds
.entry(fields_type_params[arg].clone())
.or_insert_with(HashSet::new)
.or_insert_with(HashSet::default)
.insert(trait_name_to_trait_bound(pl.trait_name));
}
}
@ -698,81 +694,31 @@ impl<'a, 'b> State<'a, 'b> {
fields: &syn::Fields,
) -> HashMap<syn::Type, HashSet<syn::TraitBound>> {
if self.type_params.is_empty() {
return HashMap::new();
return HashMap::default();
}
if let syn::Fields::Unit = fields {
return HashMap::new();
return HashMap::default();
}
// infer_fmt() uses only first field.
fields
.iter()
.take(1)
.filter_map(|field| {
self.get_type_param(&field.ty).map(|ty| {
(
ty,
[trait_name_to_trait_bound(attribute_name_to_trait_name(
self.trait_attr,
))]
.iter()
.cloned()
.collect(),
)
})
utils::get_if_type_parameter_used_in_type(&self.type_params, &field.ty)
.map(|ty| {
(
ty,
[trait_name_to_trait_bound(attribute_name_to_trait_name(
self.trait_attr,
))]
.iter()
.cloned()
.collect(),
)
})
})
.collect()
}
fn get_type_param(&self, ty: &syn::Type) -> Option<syn::Type> {
if self.has_type_param_in(ty) {
match ty {
syn::Type::Reference(syn::TypeReference { elem: ty, .. }) => {
Some(ty.deref().clone())
}
ty => Some(ty.clone()),
}
} else {
None
}
}
fn has_type_param_in(&self, ty: &syn::Type) -> bool {
match ty {
syn::Type::Path(ty) => {
if let Some(qself) = &ty.qself {
if self.has_type_param_in(&qself.ty) {
return true;
}
}
if let Some(segment) = ty.path.segments.first() {
if self.type_params.contains(&segment.ident) {
return true;
}
}
ty.path.segments.iter().any(|segment| {
if let syn::PathArguments::AngleBracketed(arguments) =
&segment.arguments
{
arguments.args.iter().any(|argument| match argument {
syn::GenericArgument::Type(ty) => {
self.has_type_param_in(ty)
}
syn::GenericArgument::Constraint(constraint) => {
self.type_params.contains(&constraint.ident)
}
_ => false,
})
} else {
false
}
})
}
syn::Type::Reference(ty) => self.has_type_param_in(&ty.elem),
_ => false,
}
}
}
/// Representation of formatting placeholder.

437
third_party/rust/derive_more/src/error.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,437 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{spanned::Spanned as _, Error, Result};
use crate::utils::{
self, AttrParams, DeriveType, FullMetaInfo, HashSet, MetaInfo, MultiFieldData,
State,
};
pub fn expand(
input: &syn::DeriveInput,
trait_name: &'static str,
) -> Result<TokenStream> {
let syn::DeriveInput {
ident, generics, ..
} = input;
let state = State::with_attr_params(
input,
trait_name,
quote!(::std::error),
trait_name.to_lowercase(),
allowed_attr_params(),
)?;
let type_params: HashSet<_> = generics
.params
.iter()
.filter_map(|generic| match generic {
syn::GenericParam::Type(ty) => Some(ty.ident.clone()),
_ => None,
})
.collect();
let (bounds, source, backtrace) = match state.derive_type {
DeriveType::Named | DeriveType::Unnamed => render_struct(&type_params, &state)?,
DeriveType::Enum => render_enum(&type_params, &state)?,
};
let source = source.map(|source| {
quote! {
fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
#source
}
}
});
let backtrace = backtrace.map(|backtrace| {
quote! {
fn backtrace(&self) -> Option<&::std::backtrace::Backtrace> {
#backtrace
}
}
});
let mut generics = generics.clone();
if !type_params.is_empty() {
let generic_parameters = generics.params.iter();
generics = utils::add_extra_where_clauses(
&generics,
quote! {
where
#ident<#(#generic_parameters),*>: ::std::fmt::Debug + ::std::fmt::Display
},
);
}
if !bounds.is_empty() {
let bounds = bounds.iter();
generics = utils::add_extra_where_clauses(
&generics,
quote! {
where
#(#bounds: ::std::fmt::Debug + ::std::fmt::Display + ::std::error::Error + 'static),*
},
);
}
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let render = quote! {
impl#impl_generics ::std::error::Error for #ident#ty_generics #where_clause {
#source
#backtrace
}
};
Ok(render)
}
fn render_struct(
type_params: &HashSet<syn::Ident>,
state: &State,
) -> Result<(HashSet<syn::Type>, Option<TokenStream>, Option<TokenStream>)> {
let parsed_fields = parse_fields(&type_params, &state)?;
let source = parsed_fields.render_source_as_struct();
let backtrace = parsed_fields.render_backtrace_as_struct();
Ok((parsed_fields.bounds, source, backtrace))
}
fn render_enum(
type_params: &HashSet<syn::Ident>,
state: &State,
) -> Result<(HashSet<syn::Type>, Option<TokenStream>, Option<TokenStream>)> {
let mut bounds = HashSet::default();
let mut source_match_arms = Vec::new();
let mut backtrace_match_arms = Vec::new();
for variant in state.enabled_variant_data().variants {
let mut default_info = FullMetaInfo::default();
default_info.enabled = true;
let state = State::from_variant(
state.input,
state.trait_name,
state.trait_module.clone(),
state.trait_attr.clone(),
allowed_attr_params(),
variant,
default_info,
)?;
let parsed_fields = parse_fields(&type_params, &state)?;
if let Some(expr) = parsed_fields.render_source_as_enum_variant_match_arm() {
source_match_arms.push(expr);
}
if let Some(expr) = parsed_fields.render_backtrace_as_enum_variant_match_arm() {
backtrace_match_arms.push(expr);
}
bounds.extend(parsed_fields.bounds.into_iter());
}
let render = |match_arms: &mut Vec<TokenStream>| {
if !match_arms.is_empty() && match_arms.len() < state.variants.len() {
match_arms.push(quote!(_ => None));
}
if !match_arms.is_empty() {
let expr = quote! {
match self {
#(#match_arms),*
}
};
Some(expr)
} else {
None
}
};
let source = render(&mut source_match_arms);
let backtrace = render(&mut backtrace_match_arms);
Ok((bounds, source, backtrace))
}
fn allowed_attr_params() -> AttrParams {
AttrParams {
enum_: vec!["ignore"],
struct_: vec!["ignore"],
variant: vec!["ignore"],
field: vec!["ignore", "source", "backtrace"],
}
}
struct ParsedFields<'input, 'state> {
data: MultiFieldData<'input, 'state>,
source: Option<usize>,
backtrace: Option<usize>,
bounds: HashSet<syn::Type>,
}
impl<'input, 'state> ParsedFields<'input, 'state> {
fn new(data: MultiFieldData<'input, 'state>) -> Self {
Self {
data,
source: None,
backtrace: None,
bounds: HashSet::default(),
}
}
}
impl<'input, 'state> ParsedFields<'input, 'state> {
fn render_source_as_struct(&self) -> Option<TokenStream> {
let source = self.source?;
let ident = &self.data.members[source];
Some(render_some(quote!(&#ident)))
}
fn render_source_as_enum_variant_match_arm(&self) -> Option<TokenStream> {
let source = self.source?;
let pattern = self.data.matcher(&[source], &[quote!(source)]);
let expr = render_some(quote!(source));
Some(quote!(#pattern => #expr))
}
fn render_backtrace_as_struct(&self) -> Option<TokenStream> {
let backtrace = self.backtrace?;
let backtrace_expr = &self.data.members[backtrace];
Some(quote!(Some(&#backtrace_expr)))
}
fn render_backtrace_as_enum_variant_match_arm(&self) -> Option<TokenStream> {
let backtrace = self.backtrace?;
let pattern = self.data.matcher(&[backtrace], &[quote!(backtrace)]);
Some(quote!(#pattern => Some(backtrace)))
}
}
fn render_some<T>(expr: T) -> TokenStream
where
T: quote::ToTokens,
{
quote!(Some(#expr as &(dyn ::std::error::Error + 'static)))
}
fn parse_fields<'input, 'state>(
type_params: &HashSet<syn::Ident>,
state: &'state State<'input>,
) -> Result<ParsedFields<'input, 'state>> {
let mut parsed_fields = match state.derive_type {
DeriveType::Named => {
parse_fields_impl(state, |attr, field, _| {
// Unwrapping is safe, cause fields in named struct
// always have an ident
let ident = field.ident.as_ref().unwrap();
match attr {
"source" => ident == "source",
"backtrace" => {
ident == "backtrace"
|| is_type_path_ends_with_segment(&field.ty, "Backtrace")
}
_ => unreachable!(),
}
})
}
DeriveType::Unnamed => {
let mut parsed_fields =
parse_fields_impl(state, |attr, field, len| match attr {
"source" => {
len == 1
&& !is_type_path_ends_with_segment(&field.ty, "Backtrace")
}
"backtrace" => {
is_type_path_ends_with_segment(&field.ty, "Backtrace")
}
_ => unreachable!(),
})?;
parsed_fields.source = parsed_fields
.source
.or_else(|| infer_source_field(&state.fields, &parsed_fields));
Ok(parsed_fields)
}
_ => unreachable!(),
}?;
if let Some(source) = parsed_fields.source {
add_bound_if_type_parameter_used_in_type(
&mut parsed_fields.bounds,
type_params,
&state.fields[source].ty,
);
}
Ok(parsed_fields)
}
/// Checks if `ty` is [`syn::Type::Path`] and ends with segment matching `tail`
/// and doesn't contain any generic parameters.
fn is_type_path_ends_with_segment(ty: &syn::Type, tail: &str) -> bool {
let ty = match ty {
syn::Type::Path(ty) => ty,
_ => return false,
};
// Unwrapping is safe, cause 'syn::TypePath.path.segments'
// have to have at least one segment
let segment = ty.path.segments.last().unwrap();
match segment.arguments {
syn::PathArguments::None => (),
_ => return false,
};
segment.ident == tail
}
fn infer_source_field(
fields: &[&syn::Field],
parsed_fields: &ParsedFields,
) -> Option<usize> {
// if we have exactly two fields
if fields.len() != 2 {
return None;
}
// no source field was specified/inferred
if parsed_fields.source.is_some() {
return None;
}
// but one of the fields was specified/inferred as backtrace field
if let Some(backtrace) = parsed_fields.backtrace {
// then infer *other field* as source field
let source = (backtrace + 1) % 2;
// unless it was explicitly marked as non-source
if parsed_fields.data.infos[source].info.source != Some(false) {
return Some(source);
}
}
None
}
fn parse_fields_impl<'input, 'state, P>(
state: &'state State<'input>,
is_valid_default_field_for_attr: P,
) -> Result<ParsedFields<'input, 'state>>
where
P: Fn(&str, &syn::Field, usize) -> bool,
{
let MultiFieldData { fields, infos, .. } = state.enabled_fields_data();
let iter = fields
.iter()
.zip(infos.iter().map(|info| &info.info))
.enumerate()
.map(|(index, (field, info))| (index, *field, info));
let source = parse_field_impl(
&is_valid_default_field_for_attr,
state.fields.len(),
iter.clone(),
"source",
|info| info.source,
)?;
let backtrace = parse_field_impl(
&is_valid_default_field_for_attr,
state.fields.len(),
iter.clone(),
"backtrace",
|info| info.backtrace,
)?;
let mut parsed_fields = ParsedFields::new(state.enabled_fields_data());
if let Some((index, _, _)) = source {
parsed_fields.source = Some(index);
}
if let Some((index, _, _)) = backtrace {
parsed_fields.backtrace = Some(index);
}
Ok(parsed_fields)
}
fn parse_field_impl<'a, P, V>(
is_valid_default_field_for_attr: &P,
len: usize,
iter: impl Iterator<Item = (usize, &'a syn::Field, &'a MetaInfo)> + Clone,
attr: &str,
value: V,
) -> Result<Option<(usize, &'a syn::Field, &'a MetaInfo)>>
where
P: Fn(&str, &syn::Field, usize) -> bool,
V: Fn(&MetaInfo) -> Option<bool>,
{
let explicit_fields = iter.clone().filter(|(_, _, info)| match value(info) {
Some(true) => true,
_ => false,
});
let inferred_fields = iter.filter(|(_, field, info)| match value(info) {
None => is_valid_default_field_for_attr(attr, field, len),
_ => false,
});
let field = assert_iter_contains_zero_or_one_item(
explicit_fields,
&format!(
"Multiple `{}` attributes specified. \
Single attribute per struct/enum variant allowed.",
attr
),
)?;
let field = match field {
field @ Some(_) => field,
None => assert_iter_contains_zero_or_one_item(
inferred_fields,
"Conflicting fields found. Consider specifying some \
`#[error(...)]` attributes to resolve conflict.",
)?,
};
Ok(field)
}
fn assert_iter_contains_zero_or_one_item<'a>(
mut iter: impl Iterator<Item = (usize, &'a syn::Field, &'a MetaInfo)>,
error_msg: &str,
) -> Result<Option<(usize, &'a syn::Field, &'a MetaInfo)>> {
let item = match iter.next() {
Some(item) => item,
None => return Ok(None),
};
if let Some((_, field, _)) = iter.next() {
return Err(Error::new(field.span(), error_msg));
}
Ok(Some(item))
}
fn add_bound_if_type_parameter_used_in_type(
bounds: &mut HashSet<syn::Type>,
type_params: &HashSet<syn::Ident>,
ty: &syn::Type,
) {
if let Some(ty) = utils::get_if_type_parameter_used_in_type(type_params, ty) {
bounds.insert(ty);
}
}

93
third_party/rust/derive_more/src/from.rs поставляемый
Просмотреть файл

@ -1,11 +1,14 @@
use crate::utils::{
add_where_clauses_for_new_ident, AttrParams, DeriveType, MultiFieldData, State,
};
use std::iter;
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use std::collections::HashMap;
use syn::{parse::Result, DeriveInput, Ident, Index};
use crate::utils::{
add_where_clauses_for_new_ident, AttrParams, DeriveType, HashMap, MultiFieldData,
RefType, State,
};
/// Provides the hook to expand `#[derive(From)]` into an implementation of `From`
pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
let state = State::with_attr_params(
@ -15,8 +18,8 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
trait_name.to_lowercase(),
AttrParams {
enum_: vec!["forward", "ignore"],
variant: vec!["forward", "ignore"],
struct_: vec!["forward"],
variant: vec!["forward", "ignore", "types"],
struct_: vec!["forward", "types"],
field: vec!["forward"],
},
)?;
@ -31,70 +34,80 @@ pub fn struct_from(input: &DeriveInput, state: &State) -> TokenStream {
let multi_field_data = state.enabled_fields_data();
let MultiFieldData {
fields,
variant_info,
infos,
input_type,
trait_path,
..
} = multi_field_data.clone();
let mut new_generics = input.generics.clone();
let sub_items: Vec<_> = infos
.iter()
.zip(fields.iter())
.enumerate()
.map(|(i, (info, field))| {
let additional_types = variant_info.additional_types(RefType::No);
let mut impls = Vec::with_capacity(additional_types.len() + 1);
for explicit_type in iter::once(None).chain(additional_types.iter().map(Some)) {
let mut new_generics = input.generics.clone();
let mut initializers = Vec::with_capacity(infos.len());
let mut from_types = Vec::with_capacity(infos.len());
for (i, (info, field)) in infos.iter().zip(fields.iter()).enumerate() {
let field_type = &field.ty;
let variable = if fields.len() == 1 {
quote!(original)
quote! { original }
} else {
let tuple_index = Index::from(i);
quote!(original.#tuple_index)
quote! { original.#tuple_index }
};
if info.forward {
if let Some(type_) = explicit_type {
initializers.push(quote! {
<#field_type as #trait_path<#type_>>::from(#variable)
});
from_types.push(quote! { #type_ });
} else if info.forward {
let type_param =
&Ident::new(&format!("__FromT{}", i), Span::call_site());
let sub_trait_path = quote!(#trait_path<#type_param>);
let sub_trait_path = quote! { #trait_path<#type_param> };
let type_where_clauses = quote! {
where #field_type: #sub_trait_path
};
new_generics = add_where_clauses_for_new_ident(
&input.generics,
&new_generics,
&[field],
type_param,
type_where_clauses,
true,
);
let casted_trait = quote!(<#field_type as #sub_trait_path>);
(quote!(#casted_trait::from(#variable)), quote!(#type_param))
let casted_trait = quote! { <#field_type as #sub_trait_path> };
initializers.push(quote! { #casted_trait::from(#variable) });
from_types.push(quote! { #type_param });
} else {
(variable, quote!(#field_type))
}
})
.collect();
let initializers: Vec<_> = sub_items.iter().map(|i| &i.0).collect();
let from_types: Vec<_> = sub_items.iter().map(|i| &i.1).collect();
let body = multi_field_data.initializer(&initializers);
let (impl_generics, _, where_clause) = new_generics.split_for_impl();
let (_, ty_generics, _) = input.generics.split_for_impl();
quote! {
impl#impl_generics #trait_path<(#(#from_types),*)> for
#input_type#ty_generics #where_clause {
#[allow(unused_variables)]
#[inline]
fn from(original: (#(#from_types),*)) -> #input_type#ty_generics {
#body
initializers.push(variable);
from_types.push(quote! { #field_type });
}
}
let body = multi_field_data.initializer(&initializers);
let (impl_generics, _, where_clause) = new_generics.split_for_impl();
let (_, ty_generics, _) = input.generics.split_for_impl();
impls.push(quote! {
#[automatically_derived]
impl#impl_generics #trait_path<(#(#from_types),*)> for
#input_type#ty_generics #where_clause {
#[inline]
fn from(original: (#(#from_types),*)) -> #input_type#ty_generics {
#body
}
}
});
}
quote! { #( #impls )* }
}
fn enum_from(input: &DeriveInput, state: State) -> TokenStream {
let mut tokens = TokenStream::new();
let mut variants_per_types = HashMap::new();
let mut variants_per_types = HashMap::default();
for variant_state in state.enabled_variant_data().variant_states {
let multi_field_data = variant_state.enabled_fields_data();
let MultiFieldData { field_types, .. } = multi_field_data.clone();
@ -112,7 +125,7 @@ fn enum_from(input: &DeriveInput, state: State) -> TokenStream {
..
} = multi_field_data.clone();
// If there would be a conflict on a empty tuple derive, ignore the
// variants that are not explicitely enabled or have explicitely enabled
// variants that are not explicitly enabled or have explicitly enabled
// or disabled fields
if field_types.is_empty()
&& variant_states.len() > 1

49
third_party/rust/derive_more/src/into.rs поставляемый
Просмотреть файл

@ -1,8 +1,11 @@
use crate::utils::{add_extra_generic_param, AttrParams, MultiFieldData, State};
use std::iter;
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse::Result, DeriveInput};
use crate::utils::{add_extra_generic_param, AttrParams, MultiFieldData, State};
/// Provides the hook to expand `#[derive(Into)]` into an implementation of `Into`
pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
let state = State::with_attr_params(
@ -13,7 +16,7 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
AttrParams {
enum_: vec!["ignore", "owned", "ref", "ref_mut"],
variant: vec!["ignore", "owned", "ref", "ref_mut"],
struct_: vec!["ignore", "owned", "ref", "ref_mut"],
struct_: vec!["ignore", "owned", "ref", "ref_mut", "types"],
field: vec!["ignore"],
},
)?;
@ -41,18 +44,40 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
input.generics.split_for_impl()
};
let into = quote! {
impl#impl_generics ::core::convert::From<#reference_with_lifetime #input_type#ty_generics> for
(#(#reference_with_lifetime #field_types),*) #where_clause {
let additional_types = variant_info.additional_types(ref_type);
for explicit_type in iter::once(None).chain(additional_types.iter().map(Some)) {
let into_types: Vec<_> = field_types
.iter()
.map(|field_type| {
// No, `.unwrap_or()` won't work here, because we use different types.
if let Some(type_) = explicit_type {
quote! { #reference_with_lifetime #type_ }
} else {
quote! { #reference_with_lifetime #field_type }
}
})
.collect();
#[allow(unused_variables)]
#[inline]
fn from(original: #reference_with_lifetime #input_type#ty_generics) -> (#(#reference_with_lifetime #field_types),*) {
(#(#reference original.#field_idents),*)
let initializers = field_idents.iter().map(|field_ident| {
if let Some(type_) = explicit_type {
quote! { <#reference #type_>::from(#reference original.#field_ident) }
} else {
quote! { #reference original.#field_ident }
}
}
};
into.to_tokens(&mut tokens);
});
(quote! {
#[automatically_derived]
impl#impl_generics ::core::convert::From<#reference_with_lifetime #input_type#ty_generics> for
(#(#into_types),*) #where_clause {
#[inline]
fn from(original: #reference_with_lifetime #input_type#ty_generics) -> (#(#into_types),*) {
(#(#initializers),*)
}
}
}).to_tokens(&mut tokens);
}
}
Ok(tokens)
}

16
third_party/rust/derive_more/src/lib.rs поставляемый
Просмотреть файл

@ -90,6 +90,11 @@
//! 1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
//! `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
//!
//! ### Error-handling traits
//! These traits are used to define error-types.
//!
//! 1. [`Error`]
//!
//! ### Operators
//!
//! These are traits that can be used for operator overloading.
@ -160,6 +165,8 @@
//!
//! [`Display`-like]: https://jeltef.github.io/derive_more/derive_more/display.html
//!
//! [`Error`]: https://jeltef.github.io/derive_more/derive_more/error.html
//!
//! [`Index`]: https://jeltef.github.io/derive_more/derive_more/index_op.html
//! [`Deref`]: https://jeltef.github.io/derive_more/derive_more/deref.html
//! [`Not`-like]: https://jeltef.github.io/derive_more/derive_more/not.html
@ -173,11 +180,12 @@
//!
//! [`Constructor`]: https://jeltef.github.io/derive_more/derive_more/constructor.html
// Suppress Clippy tips to use `matches!` macro, because minimal supported Rust version is 1.36.0.
// Remove this suppression once minimal supported Rust version is bumped up to 1.42.0 or above.
#![cfg_attr(nightly, allow(clippy::match_like_matches_macro))]
#![recursion_limit = "128"]
extern crate proc_macro;
use proc_macro2;
use syn;
use proc_macro::TokenStream;
use syn::parse::Error as ParseError;
@ -207,6 +215,8 @@ mod deref;
mod deref_mut;
#[cfg(feature = "display")]
mod display;
#[cfg(feature = "error")]
mod error;
#[cfg(feature = "from")]
mod from;
#[cfg(feature = "from_str")]
@ -352,6 +362,8 @@ create_derive!(
create_derive!("sum", sum_like, Sum, sum_derive);
create_derive!("sum", sum_like, Product, product_derive);
create_derive!("error", error, Error, error_derive, error);
create_derive!("from_str", from_str, FromStr, from_str_derive);
create_derive!("display", display, Display, display_derive, display);

Просмотреть файл

@ -56,7 +56,7 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
Ok(quote!(
impl#impl_generics #trait_path<#scalar_ident> for #input_type#ty_generics #where_clause{
#[inline]
fn #method_ident(&mut self, rhs: #scalar_ident#ty_generics) {
fn #method_ident(&mut self, rhs: #scalar_ident) {
#(#exprs;
)*
}

9
third_party/rust/derive_more/src/parsing.rs поставляемый
Просмотреть файл

@ -654,9 +654,11 @@ fn __parse_format_spec<'input>(
Matched(__pos, _) => {
let __choice_res = {
let __seq_res = {
let mut __repeat_pos =
let mut
__repeat_pos =
__pos;
let mut __repeat_value =
let mut
__repeat_value =
vec![];
loop {
let __pos =
@ -717,7 +719,8 @@ fn __parse_format_spec<'input>(
let __choice_res = {
let mut __repeat_pos =
__pos;
let mut __repeat_value = vec![];
let mut
__repeat_value = vec![];
loop {
let __pos = __repeat_pos ;
let __step_res =

Просмотреть файл

@ -4,9 +4,10 @@ use crate::utils::{
};
use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use std::collections::HashMap;
use syn::{DeriveInput, Result};
use crate::utils::HashMap;
/// Provides the hook to expand `#[derive(TryInto)]` into an implementation of `TryInto`
#[allow(clippy::cognitive_complexity)]
pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
@ -26,7 +27,7 @@ pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStre
panic!("Only enums can derive TryInto");
}
let mut variants_per_types = HashMap::new();
let mut variants_per_types = HashMap::default();
for variant_state in state.enabled_variant_data().variant_states {
let multi_field_data = variant_state.enabled_fields_data();

510
third_party/rust/derive_more/src/utils.rs поставляемый
Просмотреть файл

@ -1,16 +1,29 @@
#![cfg_attr(not(feature = "default"), allow(dead_code))]
use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens};
use syn::{
parse::{Error, Result},
parse_str,
spanned::Spanned,
Attribute, Data, DeriveInput, Field, Fields, FieldsNamed, FieldsUnnamed,
GenericParam, Generics, Ident, ImplGenerics, Index, Meta, NestedMeta, Type,
parse_quote, punctuated::Punctuated, spanned::Spanned, Attribute, Data,
DeriveInput, Error, Field, Fields, FieldsNamed, FieldsUnnamed, GenericParam,
Generics, Ident, ImplGenerics, Index, Meta, NestedMeta, Result, Token, Type,
TypeGenerics, TypeParamBound, Variant, WhereClause,
};
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
#[derive(Clone, Copy, Default)]
pub struct DeterministicState;
impl std::hash::BuildHasher for DeterministicState {
type Hasher = std::collections::hash_map::DefaultHasher;
fn build_hasher(&self) -> Self::Hasher {
Self::Hasher::default()
}
}
pub type HashMap<K, V> = std::collections::HashMap<K, V, DeterministicState>;
pub type HashSet<K> = std::collections::HashSet<K, DeterministicState>;
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub enum RefType {
No,
Ref,
@ -63,6 +76,15 @@ impl RefType {
_ => true,
}
}
pub fn from_attr_name(name: &str) -> Self {
match name {
"owned" => RefType::No,
"ref" => RefType::Ref,
"ref_mut" => RefType::Mut,
_ => panic!("'{}' is not a RefType", name),
}
}
}
pub fn numbered_vars(count: usize, prefix: &str) -> Vec<Ident> {
@ -99,10 +121,9 @@ pub fn add_extra_type_param_bound_op_output<'a>(
let mut generics = generics.clone();
for type_param in &mut generics.type_params_mut() {
let type_ident = &type_param.ident;
let bound: TypeParamBound = parse_str(
&quote!(::core::ops::#trait_ident<Output=#type_ident>).to_string(),
)
.unwrap();
let bound: TypeParamBound = parse_quote! {
::core::ops::#trait_ident<Output=#type_ident>
};
type_param.bounds.push(bound)
}
@ -121,7 +142,7 @@ pub fn add_extra_ty_param_bound<'a>(
bound: &'a TokenStream,
) -> Generics {
let mut generics = generics.clone();
let bound: TypeParamBound = parse_str(&bound.to_string()).unwrap();
let bound: TypeParamBound = parse_quote! { #bound };
for type_param in &mut generics.type_params_mut() {
type_param.bounds.push(bound.clone())
}
@ -154,7 +175,7 @@ pub fn add_extra_generic_param(
generics: &Generics,
generic_param: TokenStream,
) -> Generics {
let generic_param: GenericParam = parse_str(&generic_param.to_string()).unwrap();
let generic_param: GenericParam = parse_quote! { #generic_param };
let mut generics = generics.clone();
generics.params.push(generic_param);
@ -165,8 +186,7 @@ pub fn add_extra_where_clauses(
generics: &Generics,
type_where_clauses: TokenStream,
) -> Generics {
let mut type_where_clauses: WhereClause =
parse_str(&type_where_clauses.to_string()).unwrap();
let mut type_where_clauses: WhereClause = parse_quote! { #type_where_clauses };
let mut new_generics = generics.clone();
if let Some(old_where) = new_generics.where_clause {
type_where_clauses.predicates.extend(old_where.predicates)
@ -210,7 +230,7 @@ fn panic_one_field(trait_name: &str, trait_attr: &str) -> ! {
))
}
#[derive(PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DeriveType {
Unnamed,
Named,
@ -261,6 +281,10 @@ impl AttrParams {
field: vec![],
}
}
pub fn ignore_and_forward() -> AttrParams {
AttrParams::new(vec!["ignore", "forward"])
}
}
impl<'input> State<'input> {
@ -270,12 +294,13 @@ impl<'input> State<'input> {
trait_module: TokenStream,
trait_attr: String,
) -> Result<State<'arg_input>> {
State::with_attr_params(
State::new_impl(
input,
trait_name,
trait_module,
trait_attr,
AttrParams::default(),
true,
)
}
@ -285,12 +310,13 @@ impl<'input> State<'input> {
trait_module: TokenStream,
trait_attr: String,
) -> Result<State<'arg_input>> {
State::with_attr_params(
State::new_impl(
input,
trait_name,
trait_module,
trait_attr,
AttrParams::new(vec!["ignore"]),
true,
)
}
@ -300,12 +326,13 @@ impl<'input> State<'input> {
trait_module: TokenStream,
trait_attr: String,
) -> Result<State<'arg_input>> {
State::with_attr_params(
State::new_impl(
input,
trait_name,
trait_module,
trait_attr,
AttrParams::new(vec!["ignore", "forward"]),
true,
)
}
@ -315,12 +342,13 @@ impl<'input> State<'input> {
trait_module: TokenStream,
trait_attr: String,
) -> Result<State<'arg_input>> {
State::with_attr_params(
State::new_impl(
input,
trait_name,
trait_module,
trait_attr,
AttrParams::new(vec!["ignore", "owned", "ref", "ref_mut"]),
true,
)
}
@ -330,6 +358,42 @@ impl<'input> State<'input> {
trait_module: TokenStream,
trait_attr: String,
allowed_attr_params: AttrParams,
) -> Result<State<'arg_input>> {
State::new_impl(
input,
trait_name,
trait_module,
trait_attr,
allowed_attr_params,
true,
)
}
pub fn with_type_bound<'arg_input>(
input: &'arg_input DeriveInput,
trait_name: &'static str,
trait_module: TokenStream,
trait_attr: String,
allowed_attr_params: AttrParams,
add_type_bound: bool,
) -> Result<State<'arg_input>> {
Self::new_impl(
input,
trait_name,
trait_module,
trait_attr,
allowed_attr_params,
add_type_bound,
)
}
fn new_impl<'arg_input>(
input: &'arg_input DeriveInput,
trait_name: &'static str,
trait_module: TokenStream,
trait_attr: String,
allowed_attr_params: AttrParams,
add_type_bound: bool,
) -> Result<State<'arg_input>> {
let trait_name = trait_name.trim_end_matches("ToInner");
let trait_ident = Ident::new(trait_name, Span::call_site());
@ -352,7 +416,7 @@ impl<'input> State<'input> {
data_enum.variants.iter().collect(),
),
Data::Union(_) => {
panic!(format!("can not derive({}) for union", trait_name))
panic!(format!("cannot derive({}) for union", trait_name))
}
};
let attrs: Vec<_> = if derive_type == DeriveType::Enum {
@ -380,14 +444,32 @@ impl<'input> State<'input> {
.filter_map(|info| info.enabled.map(|_| info))
.next();
let defaults = struct_meta_info.to_full(FullMetaInfo {
// Default to enabled true, except when first attribute has explicit
// enabling
enabled: first_match.map_or(true, |info| !info.enabled.unwrap()),
// Default to enabled true, except when first attribute has explicit
// enabling.
//
// Except for derive Error.
//
// The way `else` case works is that if any field have any valid
// attribute specified, then all fields without any attributes
// specified are filtered out from `State::enabled_fields`.
//
// However, derive Error *infers* fields and there are cases when
// one of the fields may have an attribute specified, but another field
// would be inferred. So, for derive Error macro we default enabled
// to true unconditionally (i.e., even if some fields have attributes
// specified).
let default_enabled = if trait_name == "Error" {
true
} else {
first_match.map_or(true, |info| !info.enabled.unwrap())
};
let defaults = struct_meta_info.into_full(FullMetaInfo {
enabled: default_enabled,
forward: false,
// Default to owned true, except when first attribute has one of owned,
// ref or ref_mut
// - not a single attibute means default true
// - not a single attribute means default true
// - an attribute, but non of owned, ref or ref_mut means default true
// - an attribute, and owned, ref or ref_mut means default false
owned: first_match.map_or(true, |info| {
@ -399,14 +481,14 @@ impl<'input> State<'input> {
});
let full_meta_infos: Vec<_> = meta_infos
.iter()
.map(|info| info.to_full(defaults))
.into_iter()
.map(|info| info.into_full(defaults.clone()))
.collect();
let variant_states: Result<Vec<_>> = if derive_type == DeriveType::Enum {
variants
.iter()
.zip(full_meta_infos.iter().copied())
.zip(full_meta_infos.iter().cloned())
.map(|(variant, info)| {
State::from_variant(
input,
@ -422,7 +504,12 @@ impl<'input> State<'input> {
} else {
Ok(vec![])
};
let generics = add_extra_ty_param_bound(&input.generics, &trait_path);
let generics = if add_type_bound {
add_extra_ty_param_bound(&input.generics, &trait_path)
} else {
input.generics.clone()
};
Ok(State {
input,
@ -474,8 +561,8 @@ impl<'input> State<'input> {
.collect();
let meta_infos = meta_infos?;
let full_meta_infos: Vec<_> = meta_infos
.iter()
.map(|info| info.to_full(default_info))
.into_iter()
.map(|info| info.into_full(default_info.clone()))
.collect();
let generics = add_extra_ty_param_bound(&input.generics, &trait_path);
@ -519,7 +606,7 @@ impl<'input> State<'input> {
field: data.fields[0],
field_type: data.field_types[0],
member: data.members[0].clone(),
info: data.infos[0],
info: data.infos[0].clone(),
field_ident: data.field_idents[0].clone(),
trait_path: data.trait_path,
trait_path_with_params: data.trait_path_with_params.clone(),
@ -533,7 +620,7 @@ impl<'input> State<'input> {
pub fn enabled_fields_data<'state>(&'state self) -> MultiFieldData<'input, 'state> {
if self.derive_type == DeriveType::Enum {
panic!(format!("can not derive({}) for enum", self.trait_name))
panic!(format!("cannot derive({}) for enum", self.trait_name))
}
let fields = self.enabled_fields();
let field_idents = self.enabled_fields_idents();
@ -568,7 +655,7 @@ impl<'input> State<'input> {
input_type,
variant_type,
variant_name,
variant_info: self.default_info,
variant_info: self.default_info.clone(),
fields,
field_types,
field_indexes,
@ -675,7 +762,7 @@ impl<'input> State<'input> {
self.full_meta_infos
.iter()
.filter(|info| info.enabled)
.copied()
.cloned()
.collect()
}
}
@ -773,25 +860,20 @@ impl<'input, 'state> SingleFieldData<'input, 'state> {
fn get_meta_info(
trait_attr: &str,
attrs: &[Attribute],
allowed_attr_params: &[&'static str],
allowed_attr_params: &[&str],
) -> Result<MetaInfo> {
let mut it = attrs
.iter()
.filter_map(|m| m.parse_meta().ok())
.filter(|m| {
if let Some(ident) = m.path().segments.first().map(|p| &p.ident) {
ident == trait_attr
} else {
false
}
m.path()
.segments
.first()
.map(|p| p.ident == trait_attr)
.unwrap_or_default()
});
let mut info = MetaInfo {
enabled: None,
forward: None,
owned: None,
ref_: None,
ref_mut: None,
};
let mut info = MetaInfo::default();
let meta = if let Some(meta) = it.next() {
meta
@ -805,81 +887,222 @@ fn get_meta_info(
info.enabled = Some(true);
if let Some(meta2) = it.next() {
if let Some(another_meta) = it.next() {
return Err(Error::new(
meta2.span(),
another_meta.span(),
"Only a single attribute is allowed",
));
}
let list = match meta.clone() {
Meta::Path(_) => {
if allowed_attr_params.contains(&"ignore") {
return Ok(info);
} else {
return Err(Error::new(meta.span(), format!("Empty attribute is not allowed, add one of the following parameters: {}",
allowed_attr_params.join(", ")
)));
return Err(Error::new(
meta.span(),
format!(
"Empty attribute is not allowed, add one of the following parameters: {}",
allowed_attr_params.join(", "),
),
));
}
}
Meta::List(list) => list,
_ => {
return Err(Error::new(meta.span(), "Attribute format not supported1"));
}
};
for element in list.nested.into_iter() {
let nested_meta = if let NestedMeta::Meta(meta) = element {
meta
} else {
return Err(Error::new(meta.span(), "Attribute format not supported3"));
};
if let Meta::Path(_) = nested_meta {
} else {
return Err(Error::new(meta.span(), "Attribute format not supported4"));
}
let ident = if let Some(ident) =
nested_meta.path().segments.first().map(|p| &p.ident)
{
ident
} else {
return Err(Error::new(meta.span(), "Attribute format not supported5"));
};
let str_ident: &str = &ident.to_string();
if !allowed_attr_params.contains(&str_ident) {
Meta::NameValue(val) => {
return Err(Error::new(
ident.span(),
format!(
"Attribute parameter not supported. Supported attribute parameters are: {}",
allowed_attr_params.join(", ")
),
val.span(),
"Attribute doesn't support name-value format here",
));
}
};
parse_punctuated_nested_meta(&mut info, &list.nested, allowed_attr_params, None)?;
match str_ident {
"ignore" => {
info.enabled = Some(false);
}
"forward" => {
info.forward = Some(true);
}
"owned" => {
info.owned = Some(true);
}
"ref" => {
info.ref_ = Some(true);
}
"ref_mut" => {
info.ref_mut = Some(true);
}
_ => {
return Err(Error::new(meta.span(), "Attribute format not supported7"));
}
}
}
Ok(info)
}
#[derive(Copy, Clone, Debug, Default)]
fn parse_punctuated_nested_meta(
info: &mut MetaInfo,
meta: &Punctuated<NestedMeta, Token![,]>,
allowed_attr_params: &[&str],
wrapper_name: Option<&str>,
) -> Result<()> {
for meta in meta.iter() {
let meta = match meta {
NestedMeta::Meta(meta) => meta,
NestedMeta::Lit(lit) => {
return Err(Error::new(
lit.span(),
"Attribute doesn't support literals here",
))
}
};
match meta {
Meta::List(list) if list.path.is_ident("not") => {
if wrapper_name.is_some() {
// Only single top-level `not` attribute is allowed.
return Err(Error::new(
list.span(),
"Attribute doesn't support multiple multiple or nested `not` parameters",
));
}
parse_punctuated_nested_meta(
info,
&list.nested,
allowed_attr_params,
Some("not"),
)?;
}
Meta::List(list) => {
let path = &list.path;
if !allowed_attr_params.iter().any(|param| path.is_ident(param)) {
return Err(Error::new(
meta.span(),
format!(
"Attribute nested parameter not supported. \
Supported attribute parameters are: {}",
allowed_attr_params.join(", "),
),
));
}
let mut parse_nested = true;
let attr_name = path.get_ident().unwrap().to_string();
match (wrapper_name, attr_name.as_str()) {
(None, "owned") => info.owned = Some(true),
(None, "ref") => info.ref_ = Some(true),
(None, "ref_mut") => info.ref_mut = Some(true),
#[cfg(any(feature = "from", feature = "into"))]
(None, "types")
| (Some("owned"), "types")
| (Some("ref"), "types")
| (Some("ref_mut"), "types") => {
parse_nested = false;
for meta in &list.nested {
match meta {
NestedMeta::Meta(meta) => {
let path = if let Meta::Path(p) = meta {
p
} else {
return Err(Error::new(
meta.span(),
format!(
"Attribute doesn't support type {}",
quote! { #meta },
),
));
};
for ref_type in wrapper_name
.map(|n| vec![RefType::from_attr_name(n)])
.unwrap_or_else(|| {
vec![
RefType::No,
RefType::Ref,
RefType::Mut,
]
})
{
if info
.types
.entry(ref_type)
.or_default()
.replace(path.clone())
.is_some()
{
return Err(Error::new(
path.span(),
format!(
"Duplicate type `{}` specified",
quote! { #path },
),
));
}
}
}
NestedMeta::Lit(lit) => return Err(Error::new(
lit.span(),
"Attribute doesn't support nested literals here",
)),
}
}
}
_ => {
return Err(Error::new(
list.span(),
format!(
"Attribute doesn't support nested parameter `{}` here",
quote! { #path },
),
))
}
};
if parse_nested {
parse_punctuated_nested_meta(
info,
&list.nested,
allowed_attr_params,
Some(&attr_name),
)?;
}
}
Meta::Path(path) => {
if !allowed_attr_params.iter().any(|param| path.is_ident(param)) {
return Err(Error::new(
meta.span(),
format!(
"Attribute parameter not supported. \
Supported attribute parameters are: {}",
allowed_attr_params.join(", "),
),
));
}
let attr_name = path.get_ident().unwrap().to_string();
match (wrapper_name, attr_name.as_str()) {
(None, "ignore") => info.enabled = Some(false),
(None, "forward") => info.forward = Some(true),
(Some("not"), "forward") => info.forward = Some(false),
(None, "owned") => info.owned = Some(true),
(None, "ref") => info.ref_ = Some(true),
(None, "ref_mut") => info.ref_mut = Some(true),
(None, "source") => info.source = Some(true),
(Some("not"), "source") => info.source = Some(false),
(None, "backtrace") => info.backtrace = Some(true),
(Some("not"), "backtrace") => info.backtrace = Some(false),
_ => {
return Err(Error::new(
path.span(),
format!(
"Attribute doesn't support parameter `{}` here",
quote! { #path }
),
))
}
}
}
Meta::NameValue(val) => {
return Err(Error::new(
val.span(),
"Attribute doesn't support name-value parameters here",
))
}
}
}
Ok(())
}
#[derive(Clone, Debug, Default)]
pub struct FullMetaInfo {
pub enabled: bool,
pub forward: bool,
@ -889,31 +1112,34 @@ pub struct FullMetaInfo {
pub info: MetaInfo,
}
#[derive(Copy, Clone, Debug, Default)]
#[derive(Clone, Debug, Default)]
pub struct MetaInfo {
pub enabled: Option<bool>,
pub forward: Option<bool>,
pub owned: Option<bool>,
pub ref_: Option<bool>,
pub ref_mut: Option<bool>,
pub source: Option<bool>,
pub backtrace: Option<bool>,
#[cfg(any(feature = "from", feature = "into"))]
pub types: HashMap<RefType, HashSet<syn::Path>>,
}
impl MetaInfo {
fn to_full(self, defaults: FullMetaInfo) -> FullMetaInfo {
let info = self;
fn into_full(self, defaults: FullMetaInfo) -> FullMetaInfo {
FullMetaInfo {
enabled: self.enabled.unwrap_or(defaults.enabled),
forward: self.forward.unwrap_or(defaults.forward),
owned: self.owned.unwrap_or(defaults.owned),
ref_: self.ref_.unwrap_or(defaults.ref_),
ref_mut: self.ref_mut.unwrap_or(defaults.ref_mut),
info,
info: self,
}
}
}
impl FullMetaInfo {
pub fn ref_types(self) -> Vec<RefType> {
pub fn ref_types(&self) -> Vec<RefType> {
let mut ref_types = vec![];
if self.owned {
ref_types.push(RefType::No);
@ -926,4 +1152,70 @@ impl FullMetaInfo {
}
ref_types
}
#[cfg(any(feature = "from", feature = "into"))]
pub fn additional_types(&self, ref_type: RefType) -> HashSet<syn::Path> {
self.info.types.get(&ref_type).cloned().unwrap_or_default()
}
}
pub fn get_if_type_parameter_used_in_type(
type_parameters: &HashSet<syn::Ident>,
ty: &syn::Type,
) -> Option<syn::Type> {
if is_type_parameter_used_in_type(type_parameters, ty) {
match ty {
syn::Type::Reference(syn::TypeReference { elem: ty, .. }) => {
Some((&**ty).clone())
}
ty => Some(ty.clone()),
}
} else {
None
}
}
pub fn is_type_parameter_used_in_type(
type_parameters: &HashSet<syn::Ident>,
ty: &syn::Type,
) -> bool {
match ty {
syn::Type::Path(ty) => {
if let Some(qself) = &ty.qself {
if is_type_parameter_used_in_type(type_parameters, &qself.ty) {
return true;
}
}
if let Some(segment) = ty.path.segments.first() {
if type_parameters.contains(&segment.ident) {
return true;
}
}
ty.path.segments.iter().any(|segment| {
if let syn::PathArguments::AngleBracketed(arguments) =
&segment.arguments
{
arguments.args.iter().any(|argument| match argument {
syn::GenericArgument::Type(ty) => {
is_type_parameter_used_in_type(type_parameters, ty)
}
syn::GenericArgument::Constraint(constraint) => {
type_parameters.contains(&constraint.ident)
}
_ => false,
})
} else {
false
}
})
}
syn::Type::Reference(ty) => {
is_type_parameter_used_in_type(type_parameters, &ty.elem)
}
_ => false,
}
}

23
third_party/rust/derive_more/tests/add.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(Add)]
struct MyInts(i32, i32);
#[derive(Add)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(Add)]
enum MixedInts {
SmallInt(i32),
BigInt(i64),
TwoSmallInts(i32, i32),
NamedSmallInts { x: i32, y: i32 },
UnsignedOne(u32),
UnsignedTwo(u32),
Unit,
}

12
third_party/rust/derive_more/tests/add_assign.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(AddAssign)]
struct MyInts(i32, i32);
#[derive(AddAssign)]
struct Point2D {
x: i32,
y: i32,
}

108
third_party/rust/derive_more/tests/as_mut.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,108 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
use std::path::PathBuf;
use std::ptr;
#[derive(AsMut)]
struct SingleFieldTuple(String);
#[test]
fn single_field_tuple() {
let mut item = SingleFieldTuple(String::from("test"));
assert!(ptr::eq(&mut item.0, item.as_mut()));
}
#[derive(AsMut)]
#[as_mut(forward)]
struct SingleFieldForward(Vec<i32>);
#[test]
fn single_field_forward() {
let mut item = SingleFieldForward(vec![]);
let _: &mut [i32] = (&mut item).as_mut();
}
#[derive(AsMut)]
struct SingleFieldStruct {
first: String,
}
#[test]
fn single_field_struct() {
let mut item = SingleFieldStruct {
first: String::from("test"),
};
assert!(ptr::eq(&mut item.first, item.as_mut()));
}
#[derive(AsMut)]
struct MultiFieldTuple(#[as_mut] String, #[as_mut] PathBuf, Vec<usize>);
#[test]
fn multi_field_tuple() {
let mut item = MultiFieldTuple(String::from("test"), PathBuf::new(), vec![]);
assert!(ptr::eq(&mut item.0, item.as_mut()));
assert!(ptr::eq(&mut item.1, item.as_mut()));
}
#[derive(AsMut)]
struct MultiFieldStruct {
#[as_mut]
first: String,
#[as_mut]
second: PathBuf,
third: Vec<usize>,
}
#[test]
fn multi_field_struct() {
let mut item = MultiFieldStruct {
first: String::from("test"),
second: PathBuf::new(),
third: vec![],
};
assert!(ptr::eq(&mut item.first, item.as_mut()));
assert!(ptr::eq(&mut item.second, item.as_mut()));
}
#[derive(AsMut)]
struct SingleFieldGenericStruct<T> {
first: T,
}
#[test]
fn single_field_generic_struct() {
let mut item = SingleFieldGenericStruct {
first: String::from("test"),
};
assert!(ptr::eq(&mut item.first, item.as_mut()));
}
#[derive(AsMut)]
struct MultiFieldGenericStruct<T> {
#[as_mut]
first: Vec<T>,
#[as_mut]
second: PathBuf,
third: Vec<usize>,
}
#[test]
fn multi_field_generic_struct() {
let mut item = MultiFieldGenericStruct {
first: b"test".to_vec(),
second: PathBuf::new(),
third: vec![],
};
assert!(ptr::eq(&mut item.first, item.as_mut()));
assert!(ptr::eq(&mut item.second, item.as_mut()));
}

108
third_party/rust/derive_more/tests/as_ref.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,108 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
use std::path::PathBuf;
use std::ptr;
#[derive(AsRef)]
struct SingleFieldTuple(String);
#[test]
fn single_field_tuple() {
let item = SingleFieldTuple(String::from("test"));
assert!(ptr::eq(&item.0, item.as_ref()));
}
#[derive(AsRef)]
#[as_ref(forward)]
struct SingleFieldForward(Vec<i32>);
#[test]
fn single_field_forward() {
let item = SingleFieldForward(vec![]);
let _: &[i32] = (&item).as_ref();
}
#[derive(AsRef)]
struct SingleFieldStruct {
first: String,
}
#[test]
fn single_field_struct() {
let item = SingleFieldStruct {
first: String::from("test"),
};
assert!(ptr::eq(&item.first, item.as_ref()));
}
#[derive(AsRef)]
struct MultiFieldTuple(#[as_ref] String, #[as_ref] PathBuf, Vec<usize>);
#[test]
fn multi_field_tuple() {
let item = MultiFieldTuple(String::from("test"), PathBuf::new(), vec![]);
assert!(ptr::eq(&item.0, item.as_ref()));
assert!(ptr::eq(&item.1, item.as_ref()));
}
#[derive(AsRef)]
struct MultiFieldStruct {
#[as_ref]
first: String,
#[as_ref]
second: PathBuf,
third: Vec<usize>,
}
#[test]
fn multi_field_struct() {
let item = MultiFieldStruct {
first: String::from("test"),
second: PathBuf::new(),
third: vec![],
};
assert!(ptr::eq(&item.first, item.as_ref()));
assert!(ptr::eq(&item.second, item.as_ref()));
}
#[derive(AsRef)]
struct SingleFieldGenericStruct<T> {
first: T,
}
#[test]
fn single_field_generic_struct() {
let item = SingleFieldGenericStruct {
first: String::from("test"),
};
assert!(ptr::eq(&item.first, item.as_ref()));
}
#[derive(AsRef)]
struct MultiFieldGenericStruct<T, U> {
#[as_ref]
first: Vec<T>,
#[as_ref]
second: [U; 2],
third: Vec<usize>,
}
#[test]
fn multi_field_generic_struct() {
let item = MultiFieldGenericStruct {
first: b"test".to_vec(),
second: [0i32, 1i32],
third: vec![],
};
assert!(ptr::eq(&item.first, item.as_ref()));
assert!(ptr::eq(&item.second, item.as_ref()));
}

57
third_party/rust/derive_more/tests/boats_display_derive.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,57 @@
// The following code is from https://github.com/withoutboats/display_derive/blob/232a32ee19e262aacbd2c93be5b4ce9e89a5fc30/tests/tests.rs
// Written by without boats originally
#[macro_use]
extern crate derive_more;
#[derive(Display)]
#[display(fmt = "An error has occurred.")]
struct UnitError;
#[test]
fn unit_struct() {
let s = format!("{}", UnitError);
assert_eq!(&s[..], "An error has occurred.");
}
#[derive(Display)]
#[display(fmt = "Error code: {}", code)]
struct RecordError {
code: u32,
}
#[test]
fn record_struct() {
let s = format!("{}", RecordError { code: 0 });
assert_eq!(&s[..], "Error code: 0");
}
#[derive(Display)]
#[display(fmt = "Error code: {}", _0)]
struct TupleError(i32);
#[test]
fn tuple_struct() {
let s = format!("{}", TupleError(2));
assert_eq!(&s[..], "Error code: 2");
}
#[derive(Display)]
enum EnumError {
#[display(fmt = "Error code: {}", code)]
StructVariant { code: i32 },
#[display(fmt = "Error: {}", _0)]
TupleVariant(&'static str),
#[display(fmt = "An error has occurred.")]
UnitVariant,
}
#[test]
fn enum_error() {
let s = format!("{}", EnumError::StructVariant { code: 2 });
assert_eq!(&s[..], "Error code: 2");
let s = format!("{}", EnumError::TupleVariant("foobar"));
assert_eq!(&s[..], "Error: foobar");
let s = format!("{}", EnumError::UnitVariant);
assert_eq!(&s[..], "An error has occurred.");
}

21
third_party/rust/derive_more/tests/constructor.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(Constructor)]
struct EmptyTuple();
#[derive(Constructor)]
struct EmptyStruct {}
#[derive(Constructor)]
struct EmptyUnit;
#[derive(Constructor)]
struct MyInts(i32, i32);
#[derive(Constructor)]
struct Point2D {
x: i32,
y: i32,
}

68
third_party/rust/derive_more/tests/deref.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,68 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
#[derive(Deref)]
#[deref(forward)]
struct MyBoxedInt(Box<i32>);
#[derive(Deref)]
#[deref(forward)]
struct NumRef<'a> {
num: &'a i32,
}
#[derive(Deref)]
struct NumRef2<'a> {
#[deref(forward)]
num: &'a i32,
useless: bool,
}
#[derive(Deref)]
#[deref(forward)]
struct NumRef3<'a> {
num: &'a i32,
#[deref(ignore)]
useless: bool,
}
#[derive(Deref)]
struct MyInt(i32);
#[derive(Deref)]
struct Point1D {
x: i32,
}
#[derive(Deref)]
struct Point1D2 {
x: i32,
#[deref(ignore)]
useless: bool,
}
#[derive(Deref)]
struct CoolVec {
cool: bool,
#[deref]
vec: Vec<i32>,
}
#[derive(Deref)]
struct GenericVec<T>(Vec<T>);
#[test]
fn deref_generic() {
let gv = GenericVec(Vec::<i32>::new());
assert!(gv.is_empty())
}
#[derive(Deref)]
struct GenericBox<T>(#[deref(forward)] Box<T>);
#[test]
fn deref_generic_forward() {
let boxed = GenericBox(Box::new(1i32));
assert_eq!(*boxed, 1i32);
}

124
third_party/rust/derive_more/tests/deref_mut.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,124 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
#[derive(DerefMut)]
#[deref_mut(forward)]
struct MyBoxedInt(Box<i32>);
// Deref implementation is needed for DerefMut
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)
}
}
#[derive(DerefMut)]
struct NumRef<'a> {
#[deref_mut(forward)]
num: &'a mut i32,
}
// Deref implementation is needed for DerefMut
impl<'a> ::core::ops::Deref for NumRef<'a> {
type Target = <&'a mut i32 as ::core::ops::Deref>::Target;
#[inline]
fn deref(&self) -> &Self::Target {
<&'a mut i32 as ::core::ops::Deref>::deref(&self.num)
}
}
#[derive(DerefMut)]
#[deref_mut(forward)]
struct NumRef2<'a> {
num: &'a mut i32,
#[deref_mut(ignore)]
useless: bool,
}
// Deref implementation is needed for DerefMut
impl<'a> ::core::ops::Deref for NumRef2<'a> {
type Target = <&'a mut i32 as ::core::ops::Deref>::Target;
#[inline]
fn deref(&self) -> &Self::Target {
<&'a mut i32 as ::core::ops::Deref>::deref(&self.num)
}
}
#[derive(DerefMut)]
struct MyInt(i32);
// Deref implementation is needed for DerefMutToInner
impl ::core::ops::Deref for MyInt {
type Target = i32;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(DerefMut)]
struct Point1D {
x: i32,
}
// Deref implementation is needed for DerefMutToInner
impl ::core::ops::Deref for Point1D {
type Target = i32;
#[inline]
fn deref(&self) -> &Self::Target {
&self.x
}
}
#[derive(DerefMut)]
struct CoolVec {
cool: bool,
#[deref_mut]
vec: Vec<i32>,
}
impl ::core::ops::Deref for CoolVec {
type Target = Vec<i32>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.vec
}
}
#[derive(DerefMut)]
struct GenericVec<T>(Vec<T>);
impl<T> ::core::ops::Deref for GenericVec<T> {
type Target = Vec<T>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[test]
fn deref_mut_generic() {
let mut gv = GenericVec::<i32>(vec![42]);
assert!(gv.get_mut(0).is_some());
}
#[derive(DerefMut)]
struct GenericBox<T>(#[deref_mut(forward)] Box<T>);
impl<T> ::core::ops::Deref for GenericBox<T>
where
Box<T>: ::core::ops::Deref,
{
type Target = <Box<T> as ::core::ops::Deref>::Target;
#[inline]
fn deref(&self) -> &Self::Target {
<Box<T> as ::core::ops::Deref>::deref(&self.0)
}
}
#[test]
fn deref_mut_generic_forward() {
let mut boxed = GenericBox(Box::new(1i32));
*boxed = 3;
assert_eq!(*boxed, 3i32);
}

405
third_party/rust/derive_more/tests/display.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,405 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
use std::path::PathBuf;
// Here just to make sure that this doesn't conflict with
// the derives in some way
use std::fmt::Binary;
#[derive(Display, Octal, Binary)]
struct MyInt(i32);
#[derive(UpperHex)]
enum IntEnum {
U8(u8),
I8(i8),
}
#[derive(Display)]
#[display(fmt = "({}, {})", x, y)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(Display)]
#[display(fmt = "{}", message)]
struct Error {
message: &'static str,
backtrace: (),
}
impl Error {
fn new(message: &'static str) -> Self {
Self {
message,
backtrace: (),
}
}
}
#[derive(Display)]
enum E {
Uint(u32),
#[display(fmt = "I am B {:b}", i)]
Binary {
i: i8,
},
#[display(fmt = "I am C {}", "_0.display()")]
Path(PathBuf),
}
#[derive(Display)]
#[display(fmt = "Java EE")]
enum EE {
A,
B,
}
#[derive(Display)]
#[display(fmt = "Hello there!")]
union U {
i: u32,
}
#[derive(Octal)]
#[octal(fmt = "7")]
struct S;
#[derive(UpperHex)]
#[upper_hex(fmt = "UpperHex")]
struct UH;
#[derive(DebugCustom)]
#[debug(fmt = "MyDebug")]
struct D;
#[derive(Display)]
struct Unit;
#[derive(Display)]
struct UnitStruct {}
#[derive(Display)]
enum EmptyEnum {}
#[derive(Display)]
#[display(fmt = "Generic")]
struct Generic<T>(T);
#[derive(Display)]
#[display(fmt = "Here's a prefix for {} and a suffix")]
enum Affix {
A(u32),
#[display(fmt = "{} -- {}", wat, stuff)]
B {
wat: String,
stuff: bool,
},
}
#[test]
fn check_display() {
assert_eq!(MyInt(-2).to_string(), "-2");
assert_eq!(format!("{:b}", MyInt(9)), "1001");
assert_eq!(format!("{:#b}", MyInt(9)), "0b1001");
assert_eq!(format!("{:o}", MyInt(9)), "11");
assert_eq!(format!("{:X}", IntEnum::I8(-1)), "FF");
assert_eq!(format!("{:#X}", IntEnum::U8(255)), "0xFF");
assert_eq!(Point2D { x: 3, y: 4 }.to_string(), "(3, 4)");
assert_eq!(Error::new("Error").to_string(), "Error");
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!(EE::A.to_string(), "Java EE");
assert_eq!(EE::B.to_string(), "Java EE");
assert_eq!(U { i: 2 }.to_string(), "Hello there!");
assert_eq!(format!("{:o}", S), "7");
assert_eq!(format!("{:X}", UH), "UpperHex");
assert_eq!(format!("{:?}", D), "MyDebug");
assert_eq!(Unit.to_string(), "Unit");
assert_eq!(UnitStruct {}.to_string(), "UnitStruct");
assert_eq!(Generic(()).to_string(), "Generic");
assert_eq!(
Affix::A(2).to_string(),
"Here's a prefix for 2 and a suffix"
);
assert_eq!(
Affix::B {
wat: "things".to_owned(),
stuff: false,
}
.to_string(),
"Here's a prefix for things -- false and a suffix"
);
}
mod generic {
#[derive(Display)]
#[display(fmt = "Generic {}", field)]
struct NamedGenericStruct<T> {
field: T,
}
#[test]
fn named_generic_struct() {
assert_eq!(NamedGenericStruct { field: 1 }.to_string(), "Generic 1");
}
#[derive(Display)]
struct AutoNamedGenericStruct<T> {
field: T,
}
#[test]
fn auto_named_generic_struct() {
assert_eq!(AutoNamedGenericStruct { field: 1 }.to_string(), "1");
}
#[derive(Display)]
#[display(fmt = "Generic {}", "_0")]
struct UnnamedGenericStruct<T>(T);
#[test]
fn unnamed_generic_struct() {
assert_eq!(UnnamedGenericStruct(2).to_string(), "Generic 2");
}
#[derive(Display)]
struct AutoUnnamedGenericStruct<T>(T);
#[test]
fn auto_unnamed_generic_struct() {
assert_eq!(AutoUnnamedGenericStruct(2).to_string(), "2");
}
#[derive(Display)]
enum GenericEnum<A, B> {
#[display(fmt = "Gen::A {}", field)]
A { field: A },
#[display(fmt = "Gen::B {}", "_0")]
B(B),
}
#[test]
fn generic_enum() {
assert_eq!(GenericEnum::A::<_, u8> { field: 1 }.to_string(), "Gen::A 1");
assert_eq!(GenericEnum::B::<u8, _>(2).to_string(), "Gen::B 2");
}
#[derive(Display)]
enum AutoGenericEnum<A, B> {
A { field: A },
B(B),
}
#[test]
fn auto_generic_enum() {
assert_eq!(AutoGenericEnum::A::<_, u8> { field: 1 }.to_string(), "1");
assert_eq!(AutoGenericEnum::B::<u8, _>(2).to_string(), "2");
}
#[derive(Display)]
#[display(fmt = "{} {} <-> {0:o} {1:#x} <-> {0:?} {1:X?}", a, b)]
struct MultiTraitNamedGenericStruct<A, B> {
a: A,
b: B,
}
#[test]
fn multi_trait_named_generic_struct() {
let s = MultiTraitNamedGenericStruct { a: 8u8, b: 255 };
assert_eq!(s.to_string(), "8 255 <-> 10 0xff <-> 8 FF");
}
#[derive(Display)]
#[display(fmt = "{} {} {{}} {0:o} {1:#x} - {0:>4?} {1:^4X?}", "_0", "_1")]
struct MultiTraitUnnamedGenericStruct<A, B>(A, B);
#[test]
fn multi_trait_unnamed_generic_struct() {
let s = MultiTraitUnnamedGenericStruct(8u8, 255);
assert_eq!(s.to_string(), "8 255 {} 10 0xff - 8 FF ");
}
#[derive(Display)]
#[display(fmt = "{}", "3 * 4")]
struct UnusedGenericStruct<T>(T);
#[test]
fn unused_generic_struct() {
let s = UnusedGenericStruct(());
assert_eq!(s.to_string(), "12");
}
mod associated_type_field_enumerator {
use super::*;
trait Trait {
type Type;
}
struct Struct;
impl Trait for Struct {
type Type = i32;
}
#[test]
fn auto_generic_named_struct_associated() {
#[derive(Display)]
struct AutoGenericNamedStructAssociated<T: Trait> {
field: <T as Trait>::Type,
}
let s = AutoGenericNamedStructAssociated::<Struct> { field: 10 };
assert_eq!(s.to_string(), "10");
}
#[test]
fn auto_generic_unnamed_struct_associated() {
#[derive(Display)]
struct AutoGenericUnnamedStructAssociated<T: Trait>(<T as Trait>::Type);
let s = AutoGenericUnnamedStructAssociated::<Struct>(10);
assert_eq!(s.to_string(), "10");
}
#[test]
fn auto_generic_enum_associated() {
#[derive(Display)]
enum AutoGenericEnumAssociated<T: Trait> {
Enumerator(<T as Trait>::Type),
}
let e = AutoGenericEnumAssociated::<Struct>::Enumerator(10);
assert_eq!(e.to_string(), "10");
}
}
mod complex_type_field_enumerator {
use super::*;
#[derive(Display)]
struct Struct<T>(T);
#[test]
fn auto_generic_named_struct_complex() {
#[derive(Display)]
struct AutoGenericNamedStructComplex<T> {
field: Struct<T>,
}
let s = AutoGenericNamedStructComplex { field: Struct(10) };
assert_eq!(s.to_string(), "10");
}
#[test]
fn auto_generic_unnamed_struct_complex() {
#[derive(Display)]
struct AutoGenericUnnamedStructComplex<T>(Struct<T>);
let s = AutoGenericUnnamedStructComplex(Struct(10));
assert_eq!(s.to_string(), "10");
}
#[test]
fn auto_generic_enum_complex() {
#[derive(Display)]
enum AutoGenericEnumComplex<T> {
Enumerator(Struct<T>),
}
let e = AutoGenericEnumComplex::Enumerator(Struct(10));
assert_eq!(e.to_string(), "10")
}
}
mod reference {
use super::*;
#[test]
fn auto_generic_reference() {
#[derive(Display)]
struct AutoGenericReference<'a, T>(&'a T);
let s = AutoGenericReference(&10);
assert_eq!(s.to_string(), "10");
}
#[test]
fn auto_generic_static_reference() {
#[derive(Display)]
struct AutoGenericStaticReference<T: 'static>(&'static T);
let s = AutoGenericStaticReference(&10);
assert_eq!(s.to_string(), "10");
}
}
mod indirect {
use super::*;
#[derive(Display)]
struct Struct<T>(T);
#[test]
fn auto_generic_indirect() {
#[derive(Display)]
struct AutoGenericIndirect<T: 'static>(Struct<&'static T>);
const V: i32 = 10;
let s = AutoGenericIndirect(Struct(&V));
assert_eq!(s.to_string(), "10");
}
}
mod bound {
use super::*;
#[test]
fn simple() {
#[derive(Display)]
#[display(fmt = "{} {}", _0, _1)]
struct Struct<T1, T2>(T1, T2);
let s = Struct(10, 20);
assert_eq!(s.to_string(), "10 20");
}
#[test]
fn redundant() {
#[derive(Display)]
#[display(bound = "T1: ::core::fmt::Display, T2: ::core::fmt::Display")]
#[display(fmt = "{} {}", _0, _1)]
struct Struct<T1, T2>(T1, T2);
let s = Struct(10, 20);
assert_eq!(s.to_string(), "10 20");
}
#[test]
fn complex() {
trait Trait1 {
fn function1(&self) -> &'static str;
}
trait Trait2 {
fn function2(&self) -> &'static str;
}
impl Trait1 for i32 {
fn function1(&self) -> &'static str {
"WHAT"
}
}
impl Trait2 for i32 {
fn function2(&self) -> &'static str {
"EVER"
}
}
#[derive(Display)]
#[display(bound = "T1: Trait1 + Trait2, T2: Trait1 + Trait2")]
#[display(fmt = "{} {} {} {}", "_0.function1()", _0, "_1.function2()", _1)]
struct Struct<T1, T2>(T1, T2);
let s = Struct(10, 20);
assert_eq!(s.to_string(), "WHAT 10 EVER 20");
}
}
}

Просмотреть файл

@ -0,0 +1,249 @@
use super::*;
derive_display!(TestErr);
#[derive(Debug, Error)]
enum TestErr {
Unit,
NamedImplicitNoSource {
field: i32,
},
NamedImplicitSource {
source: SimpleErr,
field: i32,
},
NamedExplicitNoSource {
#[error(not(source))]
source: SimpleErr,
field: i32,
},
NamedExplicitSource {
#[error(source)]
explicit_source: SimpleErr,
field: i32,
},
NamedExplicitNoSourceRedundant {
#[error(not(source))]
field: i32,
},
NamedExplicitSourceRedundant {
#[error(source)]
source: SimpleErr,
field: i32,
},
NamedExplicitSuppressesImplicit {
source: i32,
#[error(source)]
field: SimpleErr,
},
UnnamedImplicitNoSource(i32, i32),
UnnamedImplicitSource(SimpleErr),
UnnamedExplicitNoSource(#[error(not(source))] SimpleErr),
UnnamedExplicitSource(#[error(source)] SimpleErr, i32),
UnnamedExplicitNoSourceRedundant(
#[error(not(source))] i32,
#[error(not(source))] i32,
),
UnnamedExplicitSourceRedundant(#[error(source)] SimpleErr),
NamedIgnore {
#[error(ignore)]
source: SimpleErr,
field: i32,
},
UnnamedIgnore(#[error(ignore)] SimpleErr),
NamedIgnoreRedundant {
#[error(ignore)]
field: i32,
},
UnnamedIgnoreRedundant(#[error(ignore)] i32, #[error(ignore)] i32),
#[error(ignore)]
NamedVariantIgnore {
source: SimpleErr,
field: i32,
},
#[error(ignore)]
UnnamedVariantIgnore(SimpleErr),
#[error(ignore)]
NamedVariantIgnoreRedundant {
field: i32,
},
#[error(ignore)]
UnnamedVariantIgnoreRedundant(i32, i32),
}
#[test]
fn unit() {
assert!(TestErr::Unit.source().is_none());
}
#[test]
fn named_implicit_no_source() {
let err = TestErr::NamedImplicitNoSource { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn named_implicit_source() {
let err = TestErr::NamedImplicitSource {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source() {
let err = TestErr::NamedExplicitNoSource {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn named_explicit_source() {
let err = TestErr::NamedExplicitSource {
explicit_source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source_redundant() {
let err = TestErr::NamedExplicitNoSourceRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn named_explicit_source_redundant() {
let err = TestErr::NamedExplicitSourceRedundant {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_suppresses_implicit() {
let err = TestErr::NamedExplicitSuppressesImplicit {
source: 0,
field: SimpleErr,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_implicit_no_source() {
assert!(TestErr::UnnamedImplicitNoSource(0, 0).source().is_none());
}
#[test]
fn unnamed_implicit_source() {
let err = TestErr::UnnamedImplicitSource(SimpleErr);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source() {
let err = TestErr::UnnamedExplicitNoSource(SimpleErr);
assert!(err.source().is_none());
}
#[test]
fn unnamed_explicit_source() {
let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source_redundant() {
let err = TestErr::UnnamedExplicitNoSourceRedundant(0, 0);
assert!(err.source().is_none());
}
#[test]
fn unnamed_explicit_source_redundant() {
let err = TestErr::UnnamedExplicitSourceRedundant(SimpleErr);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_ignore() {
let err = TestErr::NamedIgnore {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn unnamed_ignore() {
let err = TestErr::UnnamedIgnore(SimpleErr);
assert!(err.source().is_none());
}
#[test]
fn named_ignore_redundant() {
let err = TestErr::NamedIgnoreRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn unnamed_ignore_redundant() {
let err = TestErr::UnnamedIgnoreRedundant(0, 0);
assert!(err.source().is_none());
}
#[test]
fn named_variant_ignore() {
let err = TestErr::NamedVariantIgnore {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn unnamed_variant_ignore() {
let err = TestErr::UnnamedVariantIgnore(SimpleErr);
assert!(err.source().is_none())
}
#[test]
fn named_variant_ignore_redundant() {
let err = TestErr::NamedVariantIgnoreRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn unnamed_variant_ignore_redundant() {
let err = TestErr::UnnamedVariantIgnoreRedundant(0, 0);
assert!(err.source().is_none())
}

Просмотреть файл

@ -0,0 +1,248 @@
use super::*;
derive_display!(TestErr, T, E);
#[derive(Debug, Error)]
enum TestErr<E, T> {
Unit,
NamedImplicitNoSource {
field: T,
},
NamedImplicitSource {
source: E,
field: T,
},
NamedExplicitNoSource {
#[error(not(source))]
source: E,
field: T,
},
NamedExplicitSource {
#[error(source)]
explicit_source: E,
field: T,
},
NamedExplicitNoSourceRedundant {
#[error(not(source))]
field: T,
},
NamedExplicitSourceRedundant {
#[error(source)]
source: E,
field: T,
},
NamedExplicitSuppressesImplicit {
source: T,
#[error(source)]
field: E,
},
UnnamedImplicitNoSource(T, T),
UnnamedImplicitSource(E),
UnnamedExplicitNoSource(#[error(not(source))] E),
UnnamedExplicitSource(#[error(source)] E, T),
UnnamedExplicitNoSourceRedundant(#[error(not(source))] T, #[error(not(source))] T),
UnnamedExplicitSourceRedundant(#[error(source)] E),
NamedIgnore {
#[error(ignore)]
source: E,
field: T,
},
UnnamedIgnore(#[error(ignore)] E),
NamedIgnoreRedundant {
#[error(ignore)]
field: T,
},
UnnamedIgnoreRedundant(#[error(ignore)] T, #[error(ignore)] T),
#[error(ignore)]
NamedVariantIgnore {
source: E,
field: T,
},
#[error(ignore)]
UnnamedVariantIgnore(E),
#[error(ignore)]
NamedVariantIgnoreRedundant {
field: T,
},
#[error(ignore)]
UnnamedVariantIgnoreRedundant(T, T),
}
#[test]
fn unit() {
assert!(TestErr::<SimpleErr, i32>::Unit.source().is_none());
}
#[test]
fn named_implicit_no_source() {
let err = TestErr::<SimpleErr, _>::NamedImplicitNoSource { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn named_implicit_source() {
let err = TestErr::NamedImplicitSource {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source() {
let err = TestErr::NamedExplicitNoSource {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn named_explicit_source() {
let err = TestErr::NamedExplicitSource {
explicit_source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source_redundant() {
let err = TestErr::<SimpleErr, _>::NamedExplicitNoSourceRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn named_explicit_source_redundant() {
let err = TestErr::NamedExplicitSourceRedundant {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_suppresses_implicit() {
let err = TestErr::NamedExplicitSuppressesImplicit {
source: 0,
field: SimpleErr,
};
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_implicit_no_source() {
let err = TestErr::<SimpleErr, _>::UnnamedImplicitNoSource(0, 0);
assert!(err.source().is_none());
}
#[test]
fn unnamed_implicit_source() {
let err = TestErr::<_, i32>::UnnamedImplicitSource(SimpleErr);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source() {
let err = TestErr::<_, i32>::UnnamedExplicitNoSource(SimpleErr);
assert!(err.source().is_none());
}
#[test]
fn unnamed_explicit_source() {
let err = TestErr::UnnamedExplicitSource(SimpleErr, 0);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source_redundant() {
let err = TestErr::<SimpleErr, _>::UnnamedExplicitNoSourceRedundant(0, 0);
assert!(err.source().is_none());
}
#[test]
fn unnamed_explicit_source_redundant() {
let err = TestErr::<_, i32>::UnnamedExplicitSourceRedundant(SimpleErr);
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_ignore() {
let err = TestErr::NamedIgnore {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn unnamed_ignore() {
let err = TestErr::<_, i32>::UnnamedIgnore(SimpleErr);
assert!(err.source().is_none());
}
#[test]
fn named_ignore_redundant() {
let err = TestErr::<SimpleErr, _>::NamedIgnoreRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn unnamed_ignore_redundant() {
let err = TestErr::<SimpleErr, _>::UnnamedIgnoreRedundant(0, 0);
assert!(err.source().is_none());
}
#[test]
fn named_variant_ignore() {
let err = TestErr::NamedVariantIgnore {
source: SimpleErr,
field: 0,
};
assert!(err.source().is_none());
}
#[test]
fn unnamed_variant_ignore() {
let err = TestErr::<_, i32>::UnnamedVariantIgnore(SimpleErr);
assert!(err.source().is_none())
}
#[test]
fn named_variant_ignore_redundant() {
let err = TestErr::<SimpleErr, _>::NamedVariantIgnoreRedundant { field: 0 };
assert!(err.source().is_none());
}
#[test]
fn unnamed_variant_ignore_redundant() {
let err = TestErr::<SimpleErr, _>::UnnamedVariantIgnoreRedundant(0, 0);
assert!(err.source().is_none())
}

Просмотреть файл

@ -0,0 +1,245 @@
use super::*;
#[test]
fn named_implicit_no_source() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T> {
field: T,
}
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn named_implicit_source() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
source: E,
field: T,
}
let err = TestErr::<SimpleErr, i32>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
#[error(not(source))]
source: E,
field: T,
}
let err = TestErr::<SimpleErr, i32>::default();
assert!(err.source().is_none());
}
#[test]
fn named_explicit_source() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
#[error(source)]
explicit_source: E,
field: T,
}
let err = TestErr::<SimpleErr, i32>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T> {
#[error(not(source))]
field: T,
}
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn named_explicit_source_redundant() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
#[error(source)]
source: E,
field: T,
}
let err = TestErr::<SimpleErr, i32>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_suppresses_implicit() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
source: E,
#[error(source)]
field: T,
}
let err = TestErr::<i32, SimpleErr>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_implicit_no_source() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T>(T, T);
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn unnamed_implicit_source() {
derive_display!(TestErr, E);
#[derive(Default, Debug, Error)]
struct TestErr<E>(E);
let err = TestErr::<SimpleErr>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source() {
derive_display!(TestErr, E);
#[derive(Default, Debug, Error)]
struct TestErr<E>(#[error(not(source))] E);
assert!(TestErr::<SimpleErr>::default().source().is_none());
}
#[test]
fn unnamed_explicit_source() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T>(#[error(source)] E, T);
let err = TestErr::<SimpleErr, i32>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T>(#[error(not(source))] T, #[error(not(source))] T);
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn unnamed_explicit_source_redundant() {
derive_display!(TestErr, E);
#[derive(Default, Debug, Error)]
struct TestErr<E>(#[error(source)] E);
let err = TestErr::<SimpleErr>::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_ignore() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
struct TestErr<E, T> {
#[error(ignore)]
source: E,
field: T,
}
assert!(TestErr::<SimpleErr, i32>::default().source().is_none());
}
#[test]
fn unnamed_ignore() {
derive_display!(TestErr, E);
#[derive(Default, Debug, Error)]
struct TestErr<E>(#[error(ignore)] E);
assert!(TestErr::<SimpleErr>::default().source().is_none());
}
#[test]
fn named_ignore_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T> {
#[error(ignore)]
field: T,
}
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn unnamed_ignore_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T>(#[error(ignore)] T, #[error(ignore)] T);
assert!(TestErr::<i32>::default().source().is_none());
}
#[test]
fn named_struct_ignore() {
derive_display!(TestErr, E, T);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr<E, T> {
source: E,
field: T,
}
assert!(TestErr::<SimpleErr, i32>::default().source().is_none())
}
#[test]
fn unnamed_struct_ignore() {
derive_display!(TestErr, E);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr<E>(E);
assert!(TestErr::<SimpleErr>::default().source().is_none())
}
#[test]
fn named_struct_ignore_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr<T> {
field: T,
}
assert!(TestErr::<i32>::default().source().is_none())
}
#[test]
fn unnamed_struct_ignore_redundant() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr<T>(T, T);
assert!(TestErr::<i32>::default().source().is_none())
}

Просмотреть файл

@ -0,0 +1,249 @@
use super::*;
#[test]
fn unit() {
assert!(SimpleErr.source().is_none());
}
#[test]
fn named_implicit_no_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
field: i32,
}
assert!(TestErr::default().source().is_none());
}
#[test]
fn named_implicit_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
source: SimpleErr,
field: i32,
}
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(not(source))]
source: SimpleErr,
field: i32,
}
assert!(TestErr::default().source().is_none());
}
#[test]
fn named_explicit_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(source)]
explicit_source: SimpleErr,
field: i32,
}
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_no_source_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(not(source))]
field: i32,
}
assert!(TestErr::default().source().is_none());
}
#[test]
fn named_explicit_source_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(source)]
source: SimpleErr,
field: i32,
}
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_explicit_suppresses_implicit() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
source: i32,
#[error(source)]
field: SimpleErr,
}
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_implicit_no_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(i32, i32);
assert!(TestErr::default().source().is_none());
}
#[test]
fn unnamed_implicit_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(SimpleErr);
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(not(source))] SimpleErr);
assert!(TestErr::default().source().is_none());
}
#[test]
fn unnamed_explicit_source() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(source)] SimpleErr, i32);
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn unnamed_explicit_no_source_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(not(source))] i32, #[error(not(source))] i32);
assert!(TestErr::default().source().is_none());
}
#[test]
fn unnamed_explicit_source_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(source)] SimpleErr);
let err = TestErr::default();
assert!(err.source().is_some());
assert!(err.source().unwrap().is::<SimpleErr>());
}
#[test]
fn named_ignore() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(ignore)]
source: SimpleErr,
field: i32,
}
assert!(TestErr::default().source().is_none());
}
#[test]
fn unnamed_ignore() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(ignore)] SimpleErr);
assert!(TestErr::default().source().is_none());
}
#[test]
fn named_ignore_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
#[error(ignore)]
field: i32,
}
assert!(TestErr::default().source().is_none());
}
#[test]
fn unnamed_ignore_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(#[error(ignore)] i32, #[error(ignore)] i32);
assert!(TestErr::default().source().is_none());
}
#[test]
fn named_struct_ignore() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr {
source: SimpleErr,
field: i32,
}
assert!(TestErr::default().source().is_none())
}
#[test]
fn unnamed_struct_ignore() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr(SimpleErr);
assert!(TestErr::default().source().is_none())
}
#[test]
fn named_struct_ignore_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr {
field: i32,
}
assert!(TestErr::default().source().is_none())
}
#[test]
fn unnamed_struct_ignore_redundant() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
#[error(ignore)]
struct TestErr(i32, i32);
assert!(TestErr::default().source().is_none())
}

56
third_party/rust/derive_more/tests/error/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,56 @@
use std::error::Error;
/// Derives `std::fmt::Display` for structs/enums.
/// Derived implementation outputs empty string.
/// Useful, as a way to formally satisfy `Display` trait bound.
///
/// ## Syntax:
///
/// For regular structs/enums:
///
/// ```
/// enum MyEnum {
/// ...
/// }
///
/// derive_display!(MyEnum);
/// ```
///
/// For generic structs/enums:
///
/// ```
/// struct MyGenericStruct<T, U> {
/// ...
/// }
///
/// derive_display!(MyGenericStruct, T, U);
/// ```
macro_rules! derive_display {
(@fmt) => {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
write!(f, "")
}
};
($type:ident) => {
impl ::std::fmt::Display for $type {
derive_display!(@fmt);
}
};
($type:ident, $($type_parameters:ident),*) => {
impl<$($type_parameters),*> ::std::fmt::Display for $type<$($type_parameters),*> {
derive_display!(@fmt);
}
};
}
mod derives_for_enums_with_source;
mod derives_for_generic_enums_with_source;
mod derives_for_generic_structs_with_source;
mod derives_for_structs_with_source;
#[cfg(feature = "nightly")]
mod nightly;
derive_display!(SimpleErr);
#[derive(Default, Debug, Error)]
struct SimpleErr;

Просмотреть файл

@ -0,0 +1,272 @@
use super::*;
derive_display!(TestErr);
#[derive(Debug, Error)]
enum TestErr {
Unit,
NamedImplicitNoBacktrace {
field: i32,
},
NamedImplicitBacktraceByFieldName {
backtrace: MyBacktrace,
field: i32,
},
NamedImplicitBacktraceByFieldType {
implicit_backtrace: Backtrace,
field: i32,
},
NamedExplicitNoBacktraceByFieldName {
#[error(not(backtrace))]
backtrace: MyBacktrace,
field: i32,
},
NamedExplicitNoBacktraceByFieldType {
#[error(not(backtrace))]
implicit_backtrace: Backtrace,
field: i32,
},
NamedExplicitBacktrace {
#[error(backtrace)]
explicit_backtrace: MyBacktrace,
field: i32,
},
NamedExplicitNoBacktraceRedundant {
#[error(not(backtrace))]
not_backtrace: MyBacktrace,
#[error(not(backtrace))]
field: i32,
},
NamedExplicitBacktraceByFieldNameRedundant {
#[error(backtrace)]
backtrace: MyBacktrace,
field: i32,
},
NamedExplicitBacktraceByFieldTypeRedundant {
#[error(backtrace)]
implicit_backtrace: Backtrace,
field: i32,
},
NamedExplicitSupressesImplicit {
#[error(backtrace)]
not_backtrace: MyBacktrace,
backtrace: Backtrace,
field: i32,
},
UnnamedImplicitNoBacktrace(i32, i32),
UnnamedImplicitBacktrace(Backtrace, i32, i32),
UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, i32),
UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, i32, i32),
UnnamedExplicitNoBacktraceRedundant(
#[error(not(backtrace))] MyBacktrace,
#[error(not(backtrace))] i32,
),
UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, i32, i32),
UnnamedExplicitSupressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, i32),
}
impl TestErr {
fn get_stored_backtrace(&self) -> &Backtrace {
match self {
Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace,
Self::NamedImplicitBacktraceByFieldType {
implicit_backtrace, ..
} => implicit_backtrace,
Self::NamedExplicitBacktrace {
explicit_backtrace, ..
} => explicit_backtrace,
Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => {
backtrace
}
Self::NamedExplicitBacktraceByFieldTypeRedundant {
implicit_backtrace,
..
} => implicit_backtrace,
Self::NamedExplicitSupressesImplicit { not_backtrace, .. } => not_backtrace,
Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace,
Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace,
Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace,
Self::UnnamedExplicitSupressesImplicit(backtrace, _, _) => backtrace,
_ => panic!("ERROR IN TEST IMPLEMENTATION"),
}
}
fn get_unused_backtrace(&self) -> &Backtrace {
match self {
Self::NamedExplicitSupressesImplicit { backtrace, .. } => backtrace,
Self::UnnamedExplicitSupressesImplicit(_, backtrace, _) => backtrace,
_ => panic!("ERROR IN TEST IMPLEMENTATION"),
}
}
}
type MyBacktrace = Backtrace;
#[test]
fn unit() {
assert!(TestErr::Unit.backtrace().is_none());
}
#[test]
fn named_implicit_no_backtrace() {
let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
assert!(err.backtrace().is_none());
}
#[test]
fn named_implicit_backtrace_by_field_name() {
let err = TestErr::NamedImplicitBacktraceByFieldName {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_implicit_backtrace_by_field_type() {
let err = TestErr::NamedImplicitBacktraceByFieldType {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_no_backtrace_by_field_name() {
let err = TestErr::NamedExplicitNoBacktraceByFieldName {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_no_backtrace_by_field_type() {
let err = TestErr::NamedExplicitNoBacktraceByFieldType {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_backtrace() {
let err = TestErr::NamedExplicitBacktrace {
explicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_no_backtrace_redundant() {
let err = TestErr::NamedExplicitNoBacktraceRedundant {
not_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_backtrace_by_field_name_redundant() {
let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_backtrace_by_field_type_redundant() {
let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_supresses_implicit() {
let err = TestErr::NamedExplicitSupressesImplicit {
not_backtrace: Backtrace::force_capture(),
backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
assert_bt!(!=, err, .get_unused_backtrace);
}
#[test]
fn unnamed_implicit_no_backtrace() {
let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_implicit_backtrace() {
let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_no_backtrace() {
let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace() {
let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_no_backtrace_redundant() {
let err =
TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace_redundant() {
let err =
TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_supresses_implicit() {
let err = TestErr::UnnamedExplicitSupressesImplicit(
Backtrace::force_capture(),
(|| Backtrace::force_capture())(), // ensure backtraces are different
0,
);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
assert_bt!(!=, err, .get_unused_backtrace);
}

Просмотреть файл

@ -0,0 +1,272 @@
use super::*;
derive_display!(TestErr, T);
#[derive(Debug, Error)]
enum TestErr<T> {
Unit,
NamedImplicitNoBacktrace {
field: T,
},
NamedImplicitBacktraceByFieldName {
backtrace: MyBacktrace,
field: T,
},
NamedImplicitBacktraceByFieldType {
implicit_backtrace: Backtrace,
field: T,
},
NamedExplicitNoBacktraceByFieldName {
#[error(not(backtrace))]
backtrace: MyBacktrace,
field: T,
},
NamedExplicitNoBacktraceByFieldType {
#[error(not(backtrace))]
implicit_backtrace: Backtrace,
field: T,
},
NamedExplicitBacktrace {
#[error(backtrace)]
explicit_backtrace: MyBacktrace,
field: T,
},
NamedExplicitNoBacktraceRedundant {
#[error(not(backtrace))]
not_backtrace: MyBacktrace,
#[error(not(backtrace))]
field: T,
},
NamedExplicitBacktraceByFieldNameRedundant {
#[error(backtrace)]
backtrace: MyBacktrace,
field: T,
},
NamedExplicitBacktraceByFieldTypeRedundant {
#[error(backtrace)]
implicit_backtrace: Backtrace,
field: T,
},
NamedExplicitSupressesImplicit {
#[error(backtrace)]
not_backtrace: MyBacktrace,
backtrace: Backtrace,
field: T,
},
UnnamedImplicitNoBacktrace(T, T),
UnnamedImplicitBacktrace(Backtrace, T, T),
UnnamedExplicitNoBacktrace(#[error(not(backtrace))] Backtrace, T),
UnnamedExplicitBacktrace(#[error(backtrace)] MyBacktrace, T, T),
UnnamedExplicitNoBacktraceRedundant(
#[error(not(backtrace))] MyBacktrace,
#[error(not(backtrace))] T,
),
UnnamedExplicitBacktraceRedundant(#[error(backtrace)] Backtrace, T, T),
UnnamedExplicitSupressesImplicit(#[error(backtrace)] MyBacktrace, Backtrace, T),
}
impl<T> TestErr<T> {
fn get_stored_backtrace(&self) -> &Backtrace {
match self {
Self::NamedImplicitBacktraceByFieldName { backtrace, .. } => backtrace,
Self::NamedImplicitBacktraceByFieldType {
implicit_backtrace, ..
} => implicit_backtrace,
Self::NamedExplicitBacktrace {
explicit_backtrace, ..
} => explicit_backtrace,
Self::NamedExplicitBacktraceByFieldNameRedundant { backtrace, .. } => {
backtrace
}
Self::NamedExplicitBacktraceByFieldTypeRedundant {
implicit_backtrace,
..
} => implicit_backtrace,
Self::NamedExplicitSupressesImplicit { not_backtrace, .. } => not_backtrace,
Self::UnnamedImplicitBacktrace(backtrace, _, _) => backtrace,
Self::UnnamedExplicitBacktrace(backtrace, _, _) => backtrace,
Self::UnnamedExplicitBacktraceRedundant(backtrace, _, _) => backtrace,
Self::UnnamedExplicitSupressesImplicit(backtrace, _, _) => backtrace,
_ => panic!("ERROR IN TEST IMPLEMENTATION"),
}
}
fn get_unused_backtrace(&self) -> &Backtrace {
match self {
Self::NamedExplicitSupressesImplicit { backtrace, .. } => backtrace,
Self::UnnamedExplicitSupressesImplicit(_, backtrace, _) => backtrace,
_ => panic!("ERROR IN TEST IMPLEMENTATION"),
}
}
}
type MyBacktrace = Backtrace;
#[test]
fn unit() {
assert!(TestErr::<i32>::Unit.backtrace().is_none());
}
#[test]
fn named_implicit_no_backtrace() {
let err = TestErr::NamedImplicitNoBacktrace { field: 0 };
assert!(err.backtrace().is_none());
}
#[test]
fn named_implicit_backtrace_by_field_name() {
let err = TestErr::NamedImplicitBacktraceByFieldName {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_implicit_backtrace_by_field_type() {
let err = TestErr::NamedImplicitBacktraceByFieldType {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_no_backtrace_by_field_name() {
let err = TestErr::NamedExplicitNoBacktraceByFieldName {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_no_backtrace_by_field_type() {
let err = TestErr::NamedExplicitNoBacktraceByFieldType {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_backtrace() {
let err = TestErr::NamedExplicitBacktrace {
explicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_no_backtrace_redundant() {
let err = TestErr::NamedExplicitNoBacktraceRedundant {
not_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_none());
}
#[test]
fn named_explicit_backtrace_by_field_name_redundant() {
let err = TestErr::NamedExplicitBacktraceByFieldNameRedundant {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_backtrace_by_field_type_redundant() {
let err = TestErr::NamedExplicitBacktraceByFieldTypeRedundant {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn named_explicit_supresses_implicit() {
let err = TestErr::NamedExplicitSupressesImplicit {
not_backtrace: Backtrace::force_capture(),
backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
assert_bt!(!=, err, .get_unused_backtrace);
}
#[test]
fn unnamed_implicit_no_backtrace() {
let err = TestErr::UnnamedImplicitNoBacktrace(0, 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_implicit_backtrace() {
let err = TestErr::UnnamedImplicitBacktrace(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_no_backtrace() {
let err = TestErr::UnnamedExplicitNoBacktrace(Backtrace::force_capture(), 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace() {
let err = TestErr::UnnamedExplicitBacktrace(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_no_backtrace_redundant() {
let err =
TestErr::UnnamedExplicitNoBacktraceRedundant(Backtrace::force_capture(), 0);
assert!(err.backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace_redundant() {
let err =
TestErr::UnnamedExplicitBacktraceRedundant(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
}
#[test]
fn unnamed_explicit_supresses_implicit() {
let err = TestErr::UnnamedExplicitSupressesImplicit(
Backtrace::force_capture(),
(|| Backtrace::force_capture())(), // ensure backtraces are different
0,
);
assert!(err.backtrace().is_some());
assert_bt!(==, err, .get_stored_backtrace);
assert_bt!(!=, err, .get_unused_backtrace);
}

Просмотреть файл

@ -0,0 +1,275 @@
use super::*;
#[test]
fn named_implicit_no_backtrace() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T> {
field: T,
}
assert!(TestErr::<i32>::default().backtrace().is_none());
}
#[test]
fn named_implicit_backtrace_by_field_name() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
backtrace: MyBacktrace,
field: T,
}
type MyBacktrace = Backtrace;
let err = TestErr {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err);
}
#[test]
fn named_implicit_backtrace_by_field_type() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
implicit_backtrace: Backtrace,
field: T,
}
let err = TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, implicit_backtrace);
}
#[test]
fn named_explicit_no_backtrace_by_field_name() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(not(backtrace))]
backtrace: MyBacktrace,
field: T,
}
type MyBacktrace = Backtrace;
assert!(TestErr {
backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_no_backtrace_by_field_type() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(not(backtrace))]
implicit_backtrace: Backtrace,
field: T,
}
assert!(TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_backtrace() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(backtrace)]
explicit_backtrace: MyBacktrace,
field: T,
}
type MyBacktrace = Backtrace;
let err = TestErr {
explicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, explicit_backtrace);
}
#[test]
fn named_explicit_no_backtrace_redundant() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(not(backtrace))]
not_backtrace: MyBacktrace,
#[error(not(backtrace))]
field: T,
}
type MyBacktrace = Backtrace;
assert!(TestErr {
not_backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_backtrace_by_field_name_redundant() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(backtrace)]
backtrace: MyBacktrace,
field: T,
}
type MyBacktrace = Backtrace;
let err = TestErr {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err);
}
#[test]
fn named_explicit_backtrace_by_field_type_redundant() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(backtrace)]
implicit_backtrace: Backtrace,
field: T,
}
let err = TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, implicit_backtrace);
}
#[test]
fn named_explicit_supresses_implicit() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T> {
#[error(backtrace)]
not_backtrace: MyBacktrace,
backtrace: Backtrace,
field: T,
}
type MyBacktrace = Backtrace;
let err = TestErr {
not_backtrace: Backtrace::force_capture(),
backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, not_backtrace);
assert_bt!(!=, err);
}
#[test]
fn unnamed_implicit_no_backtrace() {
derive_display!(TestErr, T);
#[derive(Default, Debug, Error)]
struct TestErr<T>(T, T);
assert!(TestErr::<i32>::default().backtrace().is_none());
}
#[test]
fn unnamed_implicit_backtrace() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(Backtrace, T, T);
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_no_backtrace() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(#[error(not(backtrace))] Backtrace, T);
assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(#[error(backtrace)] MyBacktrace, T, T);
type MyBacktrace = Backtrace;
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_no_backtrace_redundant() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(
#[error(not(backtrace))] MyBacktrace,
#[error(not(backtrace))] T,
);
type MyBacktrace = Backtrace;
assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace_redundant() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(#[error(backtrace)] Backtrace, T, T);
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_supresses_implicit() {
derive_display!(TestErr, T);
#[derive(Debug, Error)]
struct TestErr<T>(#[error(backtrace)] MyBacktrace, Backtrace, T);
type MyBacktrace = Backtrace;
let err = TestErr(
Backtrace::force_capture(),
(|| Backtrace::force_capture())(), // ensure backtraces are different
0,
);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
assert_bt!(!=, err, 1);
}

Просмотреть файл

@ -0,0 +1,280 @@
use super::*;
#[test]
fn unit() {
assert!(SimpleErr.backtrace().is_none());
}
#[test]
fn named_implicit_no_backtrace() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr {
field: i32,
}
assert!(TestErr::default().backtrace().is_none());
}
#[test]
fn named_implicit_backtrace_by_field_name() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
backtrace: MyBacktrace,
field: i32,
}
type MyBacktrace = Backtrace;
let err = TestErr {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err);
}
#[test]
fn named_implicit_backtrace_by_field_type() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
implicit_backtrace: Backtrace,
field: i32,
}
let err = TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, implicit_backtrace);
}
#[test]
fn named_explicit_no_backtrace_by_field_name() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(not(backtrace))]
backtrace: MyBacktrace,
field: i32,
}
type MyBacktrace = Backtrace;
assert!(TestErr {
backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_no_backtrace_by_field_type() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(not(backtrace))]
implicit_backtrace: Backtrace,
field: i32,
}
assert!(TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_backtrace() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(backtrace)]
explicit_backtrace: MyBacktrace,
field: i32,
}
type MyBacktrace = Backtrace;
let err = TestErr {
explicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, explicit_backtrace);
}
#[test]
fn named_explicit_no_backtrace_redundant() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(not(backtrace))]
not_backtrace: MyBacktrace,
#[error(not(backtrace))]
field: i32,
}
type MyBacktrace = Backtrace;
assert!(TestErr {
not_backtrace: Backtrace::force_capture(),
field: 0
}
.backtrace()
.is_none());
}
#[test]
fn named_explicit_backtrace_by_field_name_redundant() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(backtrace)]
backtrace: MyBacktrace,
field: i32,
}
type MyBacktrace = Backtrace;
let err = TestErr {
backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err);
}
#[test]
fn named_explicit_backtrace_by_field_type_redundant() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(backtrace)]
implicit_backtrace: Backtrace,
field: i32,
}
let err = TestErr {
implicit_backtrace: Backtrace::force_capture(),
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, implicit_backtrace);
}
#[test]
fn named_explicit_supresses_implicit() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr {
#[error(backtrace)]
not_backtrace: MyBacktrace,
backtrace: Backtrace,
field: i32,
}
type MyBacktrace = Backtrace;
let err = TestErr {
not_backtrace: Backtrace::force_capture(),
backtrace: (|| Backtrace::force_capture())(), // ensure backtraces are different
field: 0,
};
assert!(err.backtrace().is_some());
assert_bt!(==, err, not_backtrace);
assert_bt!(!=, err);
}
#[test]
fn unnamed_implicit_no_backtrace() {
derive_display!(TestErr);
#[derive(Default, Debug, Error)]
struct TestErr(i32, i32);
assert!(TestErr::default().backtrace().is_none());
}
#[test]
fn unnamed_implicit_backtrace() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(Backtrace, i32, i32);
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_no_backtrace() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(#[error(not(backtrace))] Backtrace, i32);
assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(#[error(backtrace)] MyBacktrace, i32, i32);
type MyBacktrace = Backtrace;
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_no_backtrace_redundant() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(
#[error(not(backtrace))] MyBacktrace,
#[error(not(backtrace))] i32,
);
type MyBacktrace = Backtrace;
assert!(TestErr(Backtrace::force_capture(), 0).backtrace().is_none());
}
#[test]
fn unnamed_explicit_backtrace_redundant() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(#[error(backtrace)] Backtrace, i32, i32);
let err = TestErr(Backtrace::force_capture(), 0, 0);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
}
#[test]
fn unnamed_explicit_supresses_implicit() {
derive_display!(TestErr);
#[derive(Debug, Error)]
struct TestErr(#[error(backtrace)] MyBacktrace, Backtrace, i32);
type MyBacktrace = Backtrace;
let err = TestErr(
Backtrace::force_capture(),
(|| Backtrace::force_capture())(), // ensure backtraces are different
0,
);
assert!(err.backtrace().is_some());
assert_bt!(==, err, 0);
assert_bt!(!=, err, 1);
}

85
third_party/rust/derive_more/tests/error/nightly/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,85 @@
use std::backtrace::Backtrace;
use super::*;
/// Asserts that backtrace returned by `Error::backtrace` method equals/not-equals
/// backtrace stored in object itself.
///
/// Comparison is done by converting backtraces to strings
/// and then comparing these strings.
///
/// ## Syntax
///
/// * Equals: `assert_bt!(==, ...)`
/// * Not-equals: `assert_bt!(!=, ...)`
///
/// ### Backtrace Access
///
/// Shortcut for named-structs with `backtrace` field.
/// Access backtrace as `error.backtrace`.
///
/// ```
/// assert_bt!(==, error);
/// ```
///
/// Full form for named- and tuple-structs.
/// Access backtrace as `error.some_other_field` and `error.1` respectively.
///
/// ```
/// assert_bt!(!=, error, some_other_field);
/// assert_bt!(==, error, 1);
/// ```
///
/// Access as a method call.
/// Useful for enums (i.e., you can define a method that will match on enum variants
/// and return backtrace for each variant).
/// Access backtrace as `error.get_stored_backtrace_method()`.
///
/// ```
/// assert_bt!(!=, error, .get_stored_backtrace_method);
/// ```
macro_rules! assert_bt {
(@impl $macro:ident, $error:expr, $backtrace:expr) => {
$macro!($error.backtrace().unwrap().to_string(), $backtrace.to_string());
};
(@expand $macro:ident, $error:expr, .$backtrace:ident) => {
assert_bt!(@impl $macro, $error, $error.$backtrace())
};
(@expand $macro:ident, $error:expr, $backtrace:tt) => {
assert_bt!(@impl $macro, $error, $error.$backtrace)
};
(@expand $macro:ident, $error:expr) => {
assert_bt!(@expand $macro, $error, backtrace)
};
(==, $($args:tt)*) => {
assert_bt!(@expand assert_eq, $($args)*)
};
(!=, $($args:tt)*) => {
assert_bt!(@expand assert_ne, $($args)*)
};
}
mod derives_for_enums_with_backtrace;
mod derives_for_generic_enums_with_backtrace;
mod derives_for_generic_structs_with_backtrace;
mod derives_for_structs_with_backtrace;
derive_display!(BacktraceErr);
#[derive(Debug)]
struct BacktraceErr {
backtrace: Backtrace,
}
impl Default for BacktraceErr {
fn default() -> Self {
Self {
backtrace: Backtrace::force_capture(),
}
}
}
impl Error for BacktraceErr {
fn backtrace(&self) -> Option<&Backtrace> {
Some(&self.backtrace)
}
}

6
third_party/rust/derive_more/tests/error_tests.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,6 @@
#![cfg_attr(feature = "nightly", feature(backtrace))]
#[macro_use]
extern crate derive_more;
mod error;

171
third_party/rust/derive_more/tests/from.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,171 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(From)]
struct EmptyTuple();
#[derive(From)]
struct EmptyStruct {}
#[derive(From)]
struct EmptyUnit;
#[derive(From)]
struct MyInt(i32);
#[derive(From)]
struct MyInts(i32, i32);
#[derive(From)]
struct Point1D {
x: i32,
}
#[derive(From)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(From)]
enum MixedInts {
SmallInt(i32),
NamedBigInt {
int: i64,
},
TwoSmallInts(i32, i32),
NamedBigInts {
x: i64,
y: i64,
},
#[from(ignore)]
Unsigned(u32),
NamedUnsigned {
x: u32,
},
}
#[derive(PartialEq, Eq, Debug)]
#[derive(From)]
#[from(forward)]
struct MyIntForward(u64);
#[test]
fn forward_struct() {
assert_eq!(MyIntForward(42), 42u32.into());
assert_eq!(MyIntForward(42), 42u16.into());
assert_eq!(MyIntForward(42), 42u64.into());
}
#[derive(PartialEq, Eq, Debug)]
#[derive(From)]
enum MixedIntsForward {
#[from(forward)]
SmallInt(i32),
NamedBigInt {
int: i64,
},
}
#[test]
fn forward_enum() {
assert_eq!(MixedIntsForward::SmallInt(42), 42i32.into());
assert_eq!(MixedIntsForward::SmallInt(42), 42i16.into());
}
#[derive(From, PartialEq)]
enum AutoIgnore {
SmallInt(i32),
Uninteresting,
Uninteresting2,
}
#[test]
fn auto_ignore_variants() {
assert!(AutoIgnore::SmallInt(42) == 42i32.into());
}
#[derive(From, PartialEq)]
enum AutoIgnoreWithDefaultTrue {
#[from(ignore)]
SmallInt(i32),
Uninteresting,
Uninteresting2,
}
#[derive(From, PartialEq)]
enum AutoIgnoreWithForwardFields2 {
#[from(forward)]
SmallInt(i32),
SmallIntIgnore(i32),
}
#[test]
fn auto_ignore_with_forward_field2() {
assert!(AutoIgnoreWithForwardFields2::SmallInt(42) == 42i32.into());
assert!(AutoIgnoreWithForwardFields2::SmallInt(42) == 42i16.into());
}
#[derive(Debug, Eq, PartialEq)]
#[derive(From)]
#[from(types(u8, u16, u32))]
struct MyIntExplicit(u64);
#[test]
fn explicit_types_struct() {
assert_eq!(MyIntExplicit(42), 42u8.into());
assert_eq!(MyIntExplicit(42), 42u16.into());
assert_eq!(MyIntExplicit(42), 42u32.into());
assert_eq!(MyIntExplicit(42), 42u64.into());
}
#[derive(Debug, Eq, PartialEq)]
#[derive(From)]
#[from(types(i8, i16))]
struct MyIntsExplicit(i32, i32);
#[test]
fn explicit_types_struct_tupled() {
assert_eq!(MyIntsExplicit(42, 42), (42i32, 42i32).into());
assert_eq!(MyIntsExplicit(42, 42), (42i8, 42i8).into());
assert_eq!(MyIntsExplicit(42, 42), (42i16, 42i16).into());
}
#[derive(Debug, Eq, PartialEq)]
#[derive(From)]
enum MixedIntsExplicit {
#[from(types(i8))]
SmallInt(i32),
#[from(types(i16, i64))]
AnotherInt(i128),
NamedBigInt {
int: i64,
},
}
#[test]
fn explicit_types_enum() {
assert_eq!(MixedIntsExplicit::SmallInt(42), 42i32.into());
assert_eq!(MixedIntsExplicit::SmallInt(42), 42i8.into());
assert_eq!(MixedIntsExplicit::AnotherInt(42), 42i128.into());
assert_eq!(MixedIntsExplicit::AnotherInt(42), 42i64.into());
assert_eq!(MixedIntsExplicit::AnotherInt(42), 42i16.into());
}
#[derive(Debug, Eq, PartialEq)]
#[derive(From)]
#[from(types(i8, i16))]
struct Point2DExplicit {
x: i32,
y: i32,
}
#[test]
fn explicit_types_point_2d() {
let expected = Point2DExplicit { x: 42, y: 42 };
assert_eq!(expected, (42i32, 42i32).into());
assert_eq!(expected, (42i8, 42i8).into());
assert_eq!(expected, (42i16, 42i16).into());
}

11
third_party/rust/derive_more/tests/from_str.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,11 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(FromStr)]
struct MyInt(i32);
#[derive(FromStr)]
struct Point1D {
x: i32,
}

103
third_party/rust/derive_more/tests/generics.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,103 @@
#![allow(dead_code, non_camel_case_types)]
#[macro_use]
extern crate derive_more;
#[derive(
From,
FromStr,
Display,
Index,
Not,
Add,
Mul,
Sum,
IndexMut,
AddAssign,
MulAssign,
Deref,
DerefMut,
IntoIterator,
Constructor
)]
#[deref(forward)]
#[deref_mut(forward)]
#[into_iterator(owned, ref, ref_mut)]
struct Wrapped<T: Clone>(T);
#[derive(Deref, DerefMut)]
struct Wrapped2<T: Clone>(T);
#[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)]
struct WrappedDouble<T: Clone, U: Clone>(T, U);
#[derive(From)]
#[from(forward)]
struct WrappedDouble2<T: Clone, U: Clone>(T, U);
#[derive(
From,
FromStr,
Display,
Index,
Not,
Add,
Mul,
IndexMut,
AddAssign,
MulAssign,
Deref,
DerefMut,
IntoIterator,
Constructor,
Sum
)]
#[deref(forward)]
#[deref_mut(forward)]
#[into_iterator(owned, ref, ref_mut)]
struct Struct<T: Clone> {
t: T,
}
#[derive(Deref, DerefMut)]
struct Struct2<T: Clone> {
t: T,
}
#[derive(From, Not, Add, Mul, AddAssign, MulAssign, Constructor, Sum)]
struct DoubleStruct<T: Clone, U: Clone> {
t: T,
u: U,
}
#[derive(From)]
#[from(forward)]
struct DoubleStruct2<T: Clone, U: Clone> {
t: T,
u: U,
}
#[derive(From, Not, Add)]
enum TupleEnum<T: Clone, U: Clone> {
Tuple(T),
DoubleTuple(T, U),
}
#[derive(From)]
#[from(forward)]
enum TupleEnum2<T: Clone, U: Clone, X: Clone> {
DoubleTuple(T, U),
TripleTuple(T, U, X),
}
#[derive(From, Not, Add)]
enum StructEnum<T: Clone, U: Clone> {
Struct { t: T },
DoubleStruct { t: T, u: U },
}
#[derive(From)]
#[from(forward)]
enum StructEnum2<T: Clone, U: Clone, X: Clone> {
DoubleStruct { t: T, u: U },
TripleStruct { t: T, u: U, x: X },
}

13
third_party/rust/derive_more/tests/index.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,13 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
#[derive(Index)]
struct MyVec(Vec<i32>);
#[derive(Index)]
struct Numbers {
#[index]
numbers: Vec<i32>,
useless: bool,
}

36
third_party/rust/derive_more/tests/index_mut.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
#[derive(IndexMut)]
struct MyVec(Vec<i32>);
//Index implementation is required for IndexMut
impl<__IdxT> ::core::ops::Index<__IdxT> for MyVec
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.0, idx)
}
}
#[derive(IndexMut)]
struct Numbers {
#[index_mut]
numbers: Vec<i32>,
useless: bool,
}
//Index implementation is required for IndexMut
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)
}
}

126
third_party/rust/derive_more/tests/into.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,126 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct EmptyTuple();
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct EmptyStruct {}
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct EmptyUnit;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Into)]
#[into(owned(types(i64, i128)), ref, ref_mut)]
struct MyInt(i32);
#[test]
fn explicit_types_struct_owned_only() {
assert_eq!(i32::from(MyInt(42)), 42i32);
assert_eq!(<&i32>::from(&MyInt(42)), &42i32);
assert_eq!(<&mut i32>::from(&mut MyInt(42)), &mut 42i32);
assert_eq!(i64::from(MyInt(42)), 42i64);
assert_eq!(i128::from(MyInt(42)), 42i128);
}
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct MyInts(i32, i32);
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct Point1D {
x: i32,
}
#[derive(Debug, Eq, PartialEq)]
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(Into)]
#[into(owned, ref, ref_mut)]
struct Point2DWithIgnored {
x: i32,
y: i32,
#[into(ignore)]
useless: bool,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Into)]
#[into(owned(types(i64, i128)), ref, ref_mut, types(i32))]
struct MyIntExplicit(MyInt);
#[test]
fn explicit_types_struct_all() {
let mut input = MyIntExplicit(MyInt(42));
assert_eq!(MyInt::from(input), MyInt(42));
assert_eq!(<&MyInt>::from(&input), &MyInt(42));
assert_eq!(<&mut MyInt>::from(&mut input), &mut MyInt(42));
assert_eq!(i32::from(input), 42i32);
assert_eq!(<&i32>::from(&input), &42i32);
assert_eq!(<&mut i32>::from(&mut input), &mut 42i32);
assert_eq!(i64::from(input), 42i64);
assert_eq!(i128::from(input), 42i128);
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Into)]
#[into(owned(types(i32, i64, i128)), ref(types(i32)), ref_mut(types(i32)))]
struct MyIntsExplicit(i32, MyInt, MyIntExplicit);
#[test]
fn explicit_types_struct_tupled() {
let mut input = MyIntsExplicit(42i32, MyInt(42), MyIntExplicit(MyInt(42)));
assert_eq!(
<(i32, MyInt, MyIntExplicit)>::from(input),
(42i32, MyInt(42), MyIntExplicit(MyInt(42))),
);
assert_eq!(
<(&i32, &MyInt, &MyIntExplicit)>::from(&input),
(&42i32, &MyInt(42), &MyIntExplicit(MyInt(42))),
);
assert_eq!(
<(&mut i32, &mut MyInt, &mut MyIntExplicit)>::from(&mut input),
(&mut 42i32, &mut MyInt(42), &mut MyIntExplicit(MyInt(42))),
);
assert_eq!(<(i32, i32, i32)>::from(input), (42i32, 42i32, 42i32));
assert_eq!(<(&i32, &i32, &i32)>::from(&input), (&42i32, &42i32, &42i32));
assert_eq!(
<(&mut i32, &mut i32, &mut i32)>::from(&mut input),
(&mut 42i32, &mut 42i32, &mut 42i32),
);
assert_eq!(<(i64, i64, i64)>::from(input), (42i64, 42i64, 42i64));
assert_eq!(<(i128, i128, i128)>::from(input), (42i128, 42i128, 42i128));
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[derive(Into)]
#[into(owned, ref, ref_mut, types(i32))]
struct Point2DExplicit {
x: MyInt,
y: MyInt,
}
#[test]
fn explicit_types_point_2d() {
let mut input = Point2DExplicit {
x: MyInt(42),
y: MyInt(42),
};
assert_eq!(<(i32, i32)>::from(input), (42i32, 42i32));
assert_eq!(<(&i32, &i32)>::from(&input), (&42i32, &42i32));
assert_eq!(
<(&mut i32, &mut i32)>::from(&mut input),
(&mut 42i32, &mut 42i32)
);
}

39
third_party/rust/derive_more/tests/into_iterator.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
#![allow(dead_code, unused_imports)]
#[macro_use]
extern crate derive_more;
#[derive(IntoIterator)]
#[into_iterator(owned, ref, ref_mut)]
struct MyVec(Vec<i32>);
#[derive(IntoIterator)]
#[into_iterator(owned, ref, ref_mut)]
struct Numbers {
numbers: Vec<i32>,
}
#[derive(IntoIterator)]
struct Numbers2 {
#[into_iterator(owned, ref, ref_mut)]
numbers: Vec<i32>,
useless: bool,
useless2: bool,
}
#[derive(IntoIterator)]
struct Numbers3 {
#[into_iterator(ref, ref_mut)]
numbers: Vec<i32>,
useless: bool,
useless2: bool,
}
// Test that owned is not enabled when ref/ref_mut are enabled without owned
impl ::core::iter::IntoIterator for Numbers3 {
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)
}
}

275
third_party/rust/derive_more/tests/lib.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,275 @@
#[macro_use]
extern crate derive_more;
#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Eq, PartialEq, Debug, Clone)]
#[derive(Add)]
#[derive(Mul)]
#[derive(Neg)]
#[derive(AddAssign)]
#[derive(MulAssign)]
#[derive(FromStr)]
#[derive(Display)]
#[derive(Octal)]
#[derive(Binary)]
#[derive(Deref, DerefMut)]
#[into(owned, ref, ref_mut)]
struct MyInt(i32);
#[derive(Clone, Debug, Eq, PartialEq)]
#[derive(Add)]
#[derive(Sum)]
#[derive(Mul)]
#[derive(MulAssign)]
#[derive(Product)]
#[mul(forward)]
#[mul_assign(forward)]
struct MyInt2(i32);
#[derive(Eq, PartialEq, Debug)]
#[derive(Index, IndexMut)]
#[derive(Deref, DerefMut)]
#[derive(IntoIterator)]
#[deref(forward)]
#[deref_mut(forward)]
#[into_iterator(owned, ref, ref_mut)]
struct MyVec(Vec<i32>);
#[derive(Eq, PartialEq, Debug)]
#[derive(Deref, DerefMut)]
#[deref(forward)]
#[deref_mut(forward)]
struct MyBoxedInt(Box<i32>);
#[derive(Eq, PartialEq, Debug)]
#[derive(Not)]
#[derive(From)]
struct MyBool(bool);
#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(Add)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Mul)]
#[derive(AddAssign)]
struct MyUInt(u64, u64);
#[derive(From)]
#[derive(Into)]
#[derive(Constructor)]
#[derive(FromStr)]
#[derive(Eq, PartialEq, Debug)]
#[derive(Display)]
struct SimpleStruct {
int1: u64,
}
#[derive(From)]
#[derive(Constructor)]
#[derive(Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shr, Shl)]
#[derive(Eq, PartialEq, Debug, Clone, Copy)]
#[derive(Into)]
#[derive(AddAssign)]
#[into(owned, ref, ref_mut)]
struct NormalStruct {
int1: u64,
int2: u64,
}
#[derive(From)]
#[derive(Eq, PartialEq, Debug)]
struct NestedInt(MyInt);
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum SimpleMyIntEnum {
Int(i32),
#[from(ignore)]
_UnsignedOne(u32),
_UnsignedTwo(u32),
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Neg)]
enum SimpleSignedIntEnum {
Int(i32),
Int2(i16),
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
#[derive(Neg)]
enum SimpleEnum {
Int(i32),
#[from(ignore)]
_Ints(i32, i32),
LabeledInts {
a: i32,
b: i32,
},
_SomeUnit,
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From)]
#[derive(Add, Sub)]
enum MyIntEnum {
SmallInt(i32),
BigInt(i64),
TwoInts(i32, i32),
Point2D {
x: i64,
y: i64,
},
#[from(ignore)]
_UnsignedOne(u32),
_UnsignedTwo(u32),
#[from(ignore)]
_Uints1(u64, u64),
_Uints2 {
x: u64,
y: u64,
},
Nothing,
}
#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUInt(u32, u32);
#[derive(Eq, PartialEq, Debug)]
#[derive(Add, Mul)]
struct DoubleUIntStruct {
x: u32,
y: u32,
}
#[derive(Eq, PartialEq, Debug)]
#[derive(From, Into, Constructor)]
struct Unit;
// Tests that we can forward to a path
// containing `$crate`
macro_rules! use_dollar_crate {
() => {
struct Foo;
#[derive(From)]
enum Bar {
First(#[from(forward)] $crate::Foo),
}
};
}
use_dollar_crate!();
#[test]
fn main() {
let mut myint: MyInt = 5.into();
let _: SimpleMyIntEnum = 5i32.into();
let _: MyIntEnum = 5i32.into();
let _: MyIntEnum = 6i64.into();
let _: MyIntEnum = (5i32, 8i32).into();
let _: MyIntEnum = (5i64, 8i64).into();
let _: MyIntEnum = ().into();
let int_ref: &i32 = (&myint).into();
assert_eq!(int_ref, &5);
let int_ref_mut: &mut i32 = (&mut myint).into();
assert_eq!(int_ref_mut, &mut 5);
let mut myint: MyInt = 5.into();
let _: Unit = ().into();
assert_eq!((), Unit.into());
assert_eq!(Unit, Unit::new());
assert_eq!(MyInt(5), 5.into());
assert_eq!(Ok(MyInt(5)), "5".parse());
assert_eq!(5, MyInt(5).into());
assert_eq!(MyInt(5), MyInt::new(5));
assert_eq!(-MyInt(5), (-5).into());
assert_eq!("30", format!("{}", MyInt(30)));
assert_eq!("36", format!("{:o}", MyInt(30)));
assert_eq!("100", format!("{:b}", MyInt(4)));
assert_eq!(!MyBool(true), false.into());
assert_eq!(MyIntEnum::SmallInt(5), 5.into());
assert_eq!(SimpleStruct { int1: 5 }, 5.into());
assert_eq!(5u64, SimpleStruct { int1: 5 }.into());
assert_eq!(Ok(SimpleStruct { int1: 5 }), "5".parse());
assert_eq!("5", format!("{}", SimpleStruct { int1: 5 }));
assert_eq!(NormalStruct { int1: 5, int2: 6 }, (5, 6).into());
assert_eq!(SimpleStruct { int1: 5 }, SimpleStruct::new(5));
assert_eq!(NormalStruct { int1: 5, int2: 6 }, NormalStruct::new(5, 6));
assert_eq!((5, 6), NormalStruct::new(5, 6).into());
let mut norm_struct = NormalStruct::new(5, 6);
let uints_ref: (&u64, &u64) = (&norm_struct).into();
assert_eq!((&5, &6), uints_ref);
let uints_ref_mut: (&mut u64, &mut u64) = (&mut norm_struct).into();
assert_eq!((&mut 5, &mut 6), uints_ref_mut);
assert_eq!(MyInt(4) + MyInt(1), 5.into());
myint += MyInt(3);
assert_eq!(myint, 8.into());
myint *= 5;
assert_eq!(myint, 40.into());
assert_eq!(MyInt(4) + MyInt(1), 5.into());
assert_eq!(MyUInt(4, 5) + MyUInt(1, 2), MyUInt(5, 7));
assert_eq!(MyUInt(4, 5), MyUInt::new(4, 5));
assert_eq!((4, 5), MyUInt(4, 5).into());
let mut s1 = NormalStruct { int1: 1, int2: 2 };
let s2 = NormalStruct { int1: 2, int2: 3 };
let s3 = NormalStruct { int1: 3, int2: 5 };
assert_eq!(s1 + s2, s3);
assert_eq!(s3 - s2, s1);
s1 += s2;
assert_eq!(s1, s3);
assert_eq!((SimpleMyIntEnum::Int(6) + 5.into()).unwrap(), 11.into());
assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
assert_eq!((SimpleMyIntEnum::Int(6) - 5.into()).unwrap(), 1.into());
assert_eq!(-SimpleSignedIntEnum::Int(6), (-6i32).into());
assert_eq!(
(SimpleEnum::LabeledInts { a: 6, b: 5 }
+ SimpleEnum::LabeledInts { a: 1, b: 4 })
.unwrap(),
SimpleEnum::LabeledInts { a: 7, b: 9 }
);
let _ = (MyIntEnum::SmallInt(5) + 6.into()).unwrap();
assert_eq!((-SimpleEnum::Int(5)).unwrap(), (-5).into());
assert_eq!(MyInt(50), MyInt(5) * 10);
assert_eq!(DoubleUInt(5, 6) * 10, DoubleUInt(50, 60));
// assert_eq!(DoubleUIntStruct{x:5, y:6} * 10, DoubleUIntStruct{x:50, y:60});
let mut myint = MyInt(5);
assert_eq!(5, *myint);
*myint = 7;
assert_eq!(MyInt(7), myint);
let mut my_vec = MyVec(vec![5, 8]);
assert_eq!(5, my_vec[0]);
assert_eq!(8, my_vec[1]);
my_vec[0] = 20;
assert_eq!(20, my_vec[0]);
assert_eq!((&my_vec).into_iter().next(), Some(&20));
assert_eq!((&mut my_vec).into_iter().next(), Some(&mut 20));
assert_eq!(my_vec.into_iter().next(), Some(20));
let int_vec = vec![MyInt2(2), MyInt2(3)];
assert_eq!(MyInt2(5), int_vec.clone().into_iter().sum());
assert_eq!(MyInt2(6), int_vec.clone().into_iter().product());
let mut myint2 = MyInt2(8);
myint2 *= MyInt2(4);
assert_eq!(MyInt2(32), myint2);
let mut boxed = MyBoxedInt(Box::new(5));
assert_eq!(5, *boxed);
*boxed = 7;
assert_eq!(MyBoxedInt(Box::new(7)), boxed)
}

20
third_party/rust/derive_more/tests/mul.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,20 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(Mul)]
struct MyInt(i32);
#[derive(Mul)]
struct MyInts(i32, i32);
#[derive(Mul)]
struct Point1D {
x: i32,
}
#[derive(Mul)]
struct Point2D {
x: i32,
y: i32,
}

32
third_party/rust/derive_more/tests/mul_assign.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,32 @@
#![allow(dead_code)]
use std::marker::PhantomData;
#[macro_use]
extern crate derive_more;
#[derive(MulAssign)]
struct MyInt(i32);
#[derive(MulAssign)]
struct MyInts(i32, i32);
#[derive(MulAssign)]
#[mul_assign(forward)]
struct MyIntForward(i32);
#[derive(MulAssign)]
struct Point1D {
x: i32,
}
#[derive(MulAssign)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(MulAssign)]
struct MyInt2<T> {
x: i32,
ph: PhantomData<T>,
}

74
third_party/rust/derive_more/tests/no_std.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,74 @@
#![no_std]
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(
AddAssign,
MulAssign,
Add,
Mul,
Not,
Index,
Display,
FromStr,
Into,
From,
IndexMut,
Sum,
Deref,
DerefMut,
Constructor
)]
#[into(owned, ref, ref_mut)]
struct MyInts(u64);
#[derive(Deref, DerefMut)]
#[deref(forward)]
#[deref_mut(forward)]
struct MyBoxedInt<'a>(&'a mut u64);
#[derive(
From,
FromStr,
Display,
Index,
Not,
Add,
Mul,
Sum,
IndexMut,
AddAssign,
Deref,
DerefMut,
IntoIterator,
Constructor
)]
#[deref(forward)]
#[deref_mut(forward)]
#[into_iterator(owned, ref, ref_mut)]
struct Wrapped<T: Clone>(T);
#[derive(Deref, DerefMut)]
struct Wrapped2<T: Clone>(T);
#[derive(From, Not, Add, Mul, AddAssign, Constructor, Sum)]
struct WrappedDouble<T: Clone, U: Clone>(T, U);
#[derive(Add, Not, TryInto)]
#[try_into(owned, ref, ref_mut)]
enum MixedInts {
SmallInt(i32),
BigInt(i64),
TwoSmallInts(i32, i32),
NamedSmallInts { x: i32, y: i32 },
UnsignedOne(u32),
UnsignedTwo(u32),
}
#[derive(Not, Add)]
enum EnumWithUnit {
SmallInt(i32),
Unit,
}

28
third_party/rust/derive_more/tests/not.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,28 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
#[derive(Not)]
struct MyInts(i32, i32);
#[derive(Not)]
struct Point2D {
x: i32,
y: i32,
}
#[derive(Not)]
enum MixedInts {
SmallInt(i32),
BigInt(i64),
TwoSmallInts(i32, i32),
NamedSmallInts { x: i32, y: i32 },
UnsignedOne(u32),
UnsignedTwo(u32),
}
#[derive(Not)]
enum EnumWithUnit {
SmallInt(i32),
Unit,
}

31
third_party/rust/derive_more/tests/sum.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
#[macro_use]
extern crate derive_more;
#[derive(Sum)]
struct MyInts(i32, i64);
// Add implementation is needed for Sum
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))
}
}
#[derive(Sum)]
struct Point2D {
x: i32,
y: i32,
}
impl ::core::ops::Add for Point2D {
type Output = Point2D;
#[inline]
fn add(self, rhs: Point2D) -> Point2D {
Point2D {
x: self.x.add(rhs.x),
y: self.y.add(rhs.y),
}
}
}

199
third_party/rust/derive_more/tests/try_into.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,199 @@
#![allow(dead_code)]
#[macro_use]
extern crate derive_more;
use std::convert::{TryFrom, TryInto};
// Ensure that the TryFrom macro is hygenic and doesn't break when `Result` has
// been redefined.
type Result = ();
#[derive(Clone, Copy, TryInto)]
#[try_into(owned, ref, ref_mut)]
enum MixedInts {
SmallInt(i32),
NamedBigInt {
int: i64,
},
UnsignedWithIgnoredField(#[try_into(ignore)] bool, i64),
NamedUnsignedWithIgnnoredField {
#[try_into(ignore)]
useless: bool,
x: i64,
},
TwoSmallInts(i32, i32),
NamedBigInts {
x: i64,
y: i64,
},
Unsigned(u32),
NamedUnsigned {
x: u32,
},
Unit,
#[try_into(ignore)]
Unit2,
}
#[test]
fn test_try_into() {
let mut i = MixedInts::SmallInt(42);
assert_eq!(Ok(42i32), i.try_into());
assert_eq!(Ok(&42i32), (&i).try_into());
assert_eq!(Ok(&mut 42i32), (&mut i).try_into());
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(
u32::try_from(i),
Err("Only Unsigned, NamedUnsigned can be converted to u32")
);
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let mut i = MixedInts::NamedBigInt { int: 42 };
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(Ok(42i64), i.try_into());
assert_eq!(Ok(&42i64), (&i).try_into());
assert_eq!(Ok(&mut 42i64), (&mut i).try_into());
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(
u32::try_from(i),
Err("Only Unsigned, NamedUnsigned can be converted to u32")
);
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let mut i = MixedInts::TwoSmallInts(42, 64);
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(Ok((42i32, 64i32)), i.try_into());
assert_eq!(Ok((&42i32, &64i32)), (&i).try_into());
assert_eq!(Ok((&mut 42i32, &mut 64i32)), (&mut i).try_into());
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(
u32::try_from(i),
Err("Only Unsigned, NamedUnsigned can be converted to u32")
);
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let mut i = MixedInts::NamedBigInts { x: 42, y: 64 };
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(Ok((42i64, 64i64)), i.try_into());
assert_eq!(Ok((&42i64, &64i64)), (&i).try_into());
assert_eq!(Ok((&mut 42i64, &mut 64i64)), (&mut i).try_into());
assert_eq!(
u32::try_from(i),
Err("Only Unsigned, NamedUnsigned can be converted to u32")
);
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let mut i = MixedInts::Unsigned(42);
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(Ok(42u32), i.try_into());
assert_eq!(Ok(&42u32), (&i).try_into());
assert_eq!(Ok(&mut 42u32), (&mut i).try_into());
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let mut i = MixedInts::NamedUnsigned { x: 42 };
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(Ok(42u32), i.try_into());
assert_eq!(Ok(&42u32), (&i).try_into());
assert_eq!(Ok(&mut 42u32), (&mut i).try_into());
assert_eq!(<()>::try_from(i), Err("Only Unit can be converted to ()"));
let i = MixedInts::Unit;
assert_eq!(
i32::try_from(i),
Err("Only SmallInt can be converted to i32")
);
assert_eq!(
i64::try_from(i),
Err("Only NamedBigInt, UnsignedWithIgnoredField, NamedUnsignedWithIgnnoredField can be converted to i64")
);
assert_eq!(
<(i32, i32)>::try_from(i),
Err("Only TwoSmallInts can be converted to (i32, i32)")
);
assert_eq!(
<(i64, i64)>::try_from(i),
Err("Only NamedBigInts can be converted to (i64, i64)")
);
assert_eq!(
u32::try_from(i),
Err("Only Unsigned, NamedUnsigned can be converted to u32")
);
assert_eq!(Ok(()), i.try_into());
}