diff options
Diffstat (limited to 'vendor/derive_builder/tests')
55 files changed, 2288 insertions, 0 deletions
diff --git a/vendor/derive_builder/tests/bounds_generation.rs b/vendor/derive_builder/tests/bounds_generation.rs new file mode 100644 index 000000000..b16716ec5 --- /dev/null +++ b/vendor/derive_builder/tests/bounds_generation.rs @@ -0,0 +1,78 @@ +#[macro_use] +extern crate derive_builder; + +/// A struct that deliberately doesn't implement `Clone`. +#[derive(Debug, Default, PartialEq, Eq)] +pub struct Dolor(String); + +/// Notice that this type derives Builder without disallowing +/// `Lorem<Dolor>`. +#[derive(Debug, Clone, Builder, PartialEq, Eq, Default)] +#[builder(field(private), setter(into))] +pub struct Lorem<T> { + ipsum: T, +} + +#[derive(Debug, Clone, Builder, PartialEq, Eq, Default)] +#[builder(field(private))] +pub struct VecLorem<T> { + ipsum: Vec<T>, +} + +#[derive(Debug, Clone, Builder, PartialEq, Eq)] +#[builder(pattern = "owned", field(private))] +pub struct OwnedLorem<T> { + ipsum: T, +} + +#[test] +fn generic_field_with_clone_has_builder_impl() { + assert_eq!( + LoremBuilder::default().ipsum(10).build().unwrap(), + Lorem { ipsum: 10 } + ); +} + +/// The `LoremBuilder` type does not require that `T: Clone`, so we should +/// be able to name a `LoremBuilder<Dolor>`. But all the methods are on an impl +/// bound with `T: Clone`, so we can't do anything with it. +#[test] +fn builder_with_non_clone_generic_compiles() { + let _: LoremBuilder<Dolor>; +} + +/// In this case, we're trying to emit something that converts into a thing that +/// implements clone. +#[test] +fn builder_with_into_generic_compiles() { + assert_eq!( + LoremBuilder::<String>::default().ipsum("").build().unwrap(), + Lorem::default() + ); +} + +#[test] +fn builder_with_vec_t_compiles() { + assert_eq!( + VecLoremBuilder::<String>::default() + .ipsum(vec!["Hello".to_string()]) + .build() + .unwrap(), + VecLorem { + ipsum: vec!["Hello".to_string()], + } + ); +} + +#[test] +fn generic_field_without_clone_has_owned_builder() { + assert_eq!( + OwnedLoremBuilder::default() + .ipsum(Dolor::default()) + .build() + .unwrap(), + OwnedLorem { + ipsum: Dolor::default() + } + ); +} diff --git a/vendor/derive_builder/tests/build_fn.rs b/vendor/derive_builder/tests/build_fn.rs new file mode 100644 index 000000000..2e0a83916 --- /dev/null +++ b/vendor/derive_builder/tests/build_fn.rs @@ -0,0 +1,66 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, Builder, PartialEq)] +#[builder(build_fn(skip))] +pub struct Lorem { + percentile: u8, +} + +#[derive(Debug, Builder, PartialEq)] +#[builder(build_fn(name = "finish"))] +pub struct Ipsum { + percentile: u8, +} + +impl Lorem { + pub fn new(pct: u8) -> Result<Self, String> { + if pct <= 100 { + Ok(Lorem { percentile: pct }) + } else { + Err(format!("Percentile must be between 0 and 100; was {}", pct)) + } + } +} + +impl LoremBuilder { + pub fn build(&self) -> Result<Lorem, String> { + if let Some(ref pct) = self.percentile { + Lorem::new(*pct) + } else { + Err("Percentile was not initialized".to_string()) + } + } +} + +impl IpsumBuilder { + /// This should be fine, because we renamed the generated build_fn. + #[allow(dead_code)] + fn build(&self) -> Result<Self, String> { + unimplemented!() + } +} + +#[test] +fn happy_path() { + let lorem = LoremBuilder::default().percentile(80).build().unwrap(); + assert_eq!(lorem, Lorem { percentile: 80 }); +} + +#[test] +fn uninitialized() { + let lorem_err = LoremBuilder::default().build().unwrap_err(); + assert_eq!("Percentile was not initialized", &lorem_err); +} + +#[test] +fn out_of_range() { + let lorem_err = LoremBuilder::default().percentile(120).build().unwrap_err(); + assert_eq!("Percentile must be between 0 and 100; was 120", &lorem_err); +} + +#[test] +fn rename() { + let ipsum = IpsumBuilder::default().percentile(110).finish().unwrap(); + assert_eq!(Ipsum { percentile: 110 }, ipsum); +} diff --git a/vendor/derive_builder/tests/builder_field_custom.rs b/vendor/derive_builder/tests/builder_field_custom.rs new file mode 100644 index 000000000..35e5e8eca --- /dev/null +++ b/vendor/derive_builder/tests/builder_field_custom.rs @@ -0,0 +1,51 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +use std::num::ParseIntError; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +pub struct Lorem { + #[builder(field(type = "Option<usize>", build = "self.ipsum.unwrap_or(42) + 1"))] + ipsum: usize, + + #[builder(setter(into), field(type = "String", build = "self.dolor.parse()?"))] + dolor: u32, +} + +impl From<ParseIntError> for LoremBuilderError { + fn from(e: ParseIntError) -> LoremBuilderError { + LoremBuilderError::ValidationError(e.to_string()) + } +} + +#[test] +fn custom_fields() { + let x = LoremBuilder::default().dolor("7").build().unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: 43, + dolor: 7, + } + ); + + let x = LoremBuilder::default() + .ipsum(Some(12)) + .dolor("66") + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: 13, + dolor: 66, + } + ); + + let x = LoremBuilder::default().build().unwrap_err().to_string(); + assert_eq!(x, "cannot parse integer from empty string"); +} diff --git a/vendor/derive_builder/tests/builder_name.rs b/vendor/derive_builder/tests/builder_name.rs new file mode 100644 index 000000000..3b2cd5706 --- /dev/null +++ b/vendor/derive_builder/tests/builder_name.rs @@ -0,0 +1,40 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(name = "MyBuilder")] +struct Lorem { + ipsum: &'static str, + pub dolor: Option<&'static str>, + pub sit: i32, + amet: bool, +} + +#[test] +fn error_if_uninitialized() { + let error = MyBuilder::default().build().unwrap_err(); + assert_eq!(&error.to_string(), "`ipsum` must be initialized"); +} + +#[test] +fn builder_test() { + let x: Lorem = MyBuilder::default() + .ipsum("lorem") + .dolor(Some("dolor")) + .sit(42) + .amet(true) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: "lorem", + dolor: Some("dolor"), + sit: 42, + amet: true, + } + ); +} diff --git a/vendor/derive_builder/tests/compile-fail/builder_field_attr.rs b/vendor/derive_builder/tests/compile-fail/builder_field_attr.rs new file mode 100644 index 000000000..bc1b63dea --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_field_attr.rs @@ -0,0 +1,12 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +pub struct Lorem { + ok: String, + + #[builder_field_attr(no_such_attribute)] + broken: String, +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/builder_field_attr.stderr b/vendor/derive_builder/tests/compile-fail/builder_field_attr.stderr new file mode 100644 index 000000000..83a5f3e8b --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_field_attr.stderr @@ -0,0 +1,5 @@ +error: cannot find attribute `no_such_attribute` in this scope + --> tests/compile-fail/builder_field_attr.rs:8:26 + | +8 | #[builder_field_attr(no_such_attribute)] + | ^^^^^^^^^^^^^^^^^ diff --git a/vendor/derive_builder/tests/compile-fail/builder_field_custom.rs b/vendor/derive_builder/tests/compile-fail/builder_field_custom.rs new file mode 100644 index 000000000..74c37efb5 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_field_custom.rs @@ -0,0 +1,22 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +pub struct Lorem { + // `default` is incompatible with `field.build` + #[builder( + default = "1", + field(build = "self.ipsum.map(|v| v + 42).unwrap_or(100)") + )] + ipsum: usize, + + // `default` is incompatible with `field.type`, even without `field.build` + #[builder(default = "2", field(type = "usize"))] + sit: usize, + + // Both errors can occur on the same field + #[builder(default = "3", field(type = "usize", build = "self.ipsum + 42"))] + amet: usize, +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/builder_field_custom.stderr b/vendor/derive_builder/tests/compile-fail/builder_field_custom.stderr new file mode 100644 index 000000000..6cfc7335f --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_field_custom.stderr @@ -0,0 +1,23 @@ +error: #[builder(default)] and #[builder(field(build="..."))] cannot be used together + --> tests/compile-fail/builder_field_custom.rs:8:19 + | +8 | default = "1", + | ^^^ + +error: #[builder(default)] and #[builder(field(type="..."))] cannot be used together + --> tests/compile-fail/builder_field_custom.rs:14:25 + | +14 | #[builder(default = "2", field(type = "usize"))] + | ^^^ + +error: #[builder(default)] and #[builder(field(build="..."))] cannot be used together + --> tests/compile-fail/builder_field_custom.rs:18:25 + | +18 | #[builder(default = "3", field(type = "usize", build = "self.ipsum + 42"))] + | ^^^ + +error: #[builder(default)] and #[builder(field(type="..."))] cannot be used together + --> tests/compile-fail/builder_field_custom.rs:18:25 + | +18 | #[builder(default = "3", field(type = "usize", build = "self.ipsum + 42"))] + | ^^^ diff --git a/vendor/derive_builder/tests/compile-fail/builder_setter_attr.rs b/vendor/derive_builder/tests/compile-fail/builder_setter_attr.rs new file mode 100644 index 000000000..baf690c21 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_setter_attr.rs @@ -0,0 +1,16 @@ +#![deny(unused_must_use)] + +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +pub struct Lorem { + ok: String, + + #[builder_setter_attr(must_use)] + broken: usize, +} + +fn main() { + LoremBuilder::default().broken(42); +} diff --git a/vendor/derive_builder/tests/compile-fail/builder_setter_attr.stderr b/vendor/derive_builder/tests/compile-fail/builder_setter_attr.stderr new file mode 100644 index 000000000..4b093d7d5 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/builder_setter_attr.stderr @@ -0,0 +1,11 @@ +error: unused return value of `LoremBuilder::broken` that must be used + --> tests/compile-fail/builder_setter_attr.rs:15:5 + | +15 | LoremBuilder::default().broken(42); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> tests/compile-fail/builder_setter_attr.rs:1:9 + | +1 | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ diff --git a/vendor/derive_builder/tests/compile-fail/crate_root.rs b/vendor/derive_builder/tests/compile-fail/crate_root.rs new file mode 100644 index 000000000..6f6cd3017 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/crate_root.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate derive_builder; + +// This is a stand-in for any bad crate directive +mod empty {} + +#[derive(Builder)] +// It would be nice if the "failed to resolve" errors would identify `"empty"` as the error span, +// but doing so would require rewriting a lot of the code generation to use the crate_root span +// for the full path of the thing being imported, and that doesn't seem worth the code churn. +#[builder(crate = "empty")] +struct BadCrate { + lorem: String, +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/crate_root.stderr b/vendor/derive_builder/tests/compile-fail/crate_root.stderr new file mode 100644 index 000000000..326b80aa9 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/crate_root.stderr @@ -0,0 +1,97 @@ +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ could not find `export` in `empty` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty::export::core::option` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this enum + | +5 | use derive_builder::export::core::option::Option; + | + +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty::export::core::clone` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this trait + | +5 | use derive_builder::export::core::clone::Clone; + | + +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty::export::core::result` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing one of these items + | +5 | use derive_builder::export::core::fmt::Result; + | +5 | use derive_builder::export::core::io::Result; + | +5 | use derive_builder::export::core::result::Result; + | +5 | use derive_builder::export::core::thread::Result; + | + +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty::export::core::convert` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this trait + | +5 | use derive_builder::export::core::convert::Into; + | + +error[E0433]: failed to resolve: could not find `UninitializedFieldError` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct + | +5 | use derive_builder::UninitializedFieldError; + | + +error[E0433]: failed to resolve: could not find `export` in `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty::export::core::default` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this trait + | +5 | use derive_builder::export::core::default::Default; + | + +error[E0412]: cannot find type `UninitializedFieldError` in module `empty` + --> tests/compile-fail/crate_root.rs:7:10 + | +7 | #[derive(Builder)] + | ^^^^^^^ not found in `empty` + | + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider importing this struct + | +5 | use derive_builder::UninitializedFieldError; + | diff --git a/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.rs b/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.rs new file mode 100644 index 000000000..b9b78dea2 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.rs @@ -0,0 +1,44 @@ +#[macro_use] +extern crate derive_builder; + +use derive_builder::UninitializedFieldError; + +trait Popular { + fn is_popular(&self) -> bool; +} + +impl<'a> Popular for &'a str { + fn is_popular(&self) -> bool { + !self.starts_with('b') + } +} + +#[derive(Debug, Builder)] +#[builder(build_fn(validate = "check_person", error = "Error<N>"))] +struct Person<N> { + name: N, + age: u16, +} + +enum Error<N> { + UninitializedField(&'static str), + UnpopularName(N), +} + +impl<N> From<UninitializedFieldError> for Error<N> { + fn from(error: UninitializedFieldError) -> Self { + Self::UninitializedField(error.field_name()) + } +} + +fn check_person<N: Popular + Clone>(builder: &PersonBuilder<N>) -> Result<(), Error<N>> { + if let Some(name) = &builder.name { + if !name.is_popular() { + return Err(Error::UnpopularName(name.clone())); + } + } + + Ok(()) +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.stderr b/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.stderr new file mode 100644 index 000000000..5fa9129ec --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/custom_error_generic_missing_bound.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `N: Popular` is not satisfied + --> tests/compile-fail/custom_error_generic_missing_bound.rs:17:31 + | +17 | #[builder(build_fn(validate = "check_person", error = "Error<N>"))] + | ^^^^^^^^^^^^^^ the trait `Popular` is not implemented for `N` + | +note: required by a bound in `check_person` + --> tests/compile-fail/custom_error_generic_missing_bound.rs:34:20 + | +34 | fn check_person<N: Popular + Clone>(builder: &PersonBuilder<N>) -> Result<(), Error<N>> { + | ^^^^^^^ required by this bound in `check_person` +help: consider restricting type parameter `N` + | +18 | struct Person<N: Popular> { + | +++++++++ diff --git a/vendor/derive_builder/tests/compile-fail/custom_error_no_from.rs b/vendor/derive_builder/tests/compile-fail/custom_error_no_from.rs new file mode 100644 index 000000000..f052a173f --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/custom_error_no_from.rs @@ -0,0 +1,37 @@ +#[macro_use] +extern crate derive_builder; + +fn validate_age(age: usize) -> Result<(), Error> { + if age > 200 { + Err(Error::UnrealisticAge(age)) + } else { + Ok(()) + } +} + +fn check_person(builder: &PersonBuilder) -> Result<(), Error> { + if let Some(age) = builder.age { + validate_age(age) + } else { + Ok(()) + } +} + +#[derive(Builder)] +#[builder(build_fn(validate = "check_person", error = "Error"))] +struct Person { + name: String, + age: usize, +} + +// NOTE: This enum has a variant for the uninitialized field case (called MissingData) +// but has forgotten `impl From<derive_builder::UninitializedFieldError>`, which is a +// compile-blocking mistake. +#[derive(Debug)] +enum Error { + /// A required field is not filled out. + MissingData(&'static str), + UnrealisticAge(usize), +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/custom_error_no_from.stderr b/vendor/derive_builder/tests/compile-fail/custom_error_no_from.stderr new file mode 100644 index 000000000..cde3d817b --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/custom_error_no_from.stderr @@ -0,0 +1,7 @@ +error[E0277]: the trait bound `Error: From<UninitializedFieldError>` is not satisfied + --> tests/compile-fail/custom_error_no_from.rs:21:55 + | +21 | #[builder(build_fn(validate = "check_person", error = "Error"))] + | ^^^^^^^ the trait `From<UninitializedFieldError>` is not implemented for `Error` + | + = note: required because of the requirements on the impl of `Into<Error>` for `UninitializedFieldError` diff --git a/vendor/derive_builder/tests/compile-fail/deny_empty_default.rs b/vendor/derive_builder/tests/compile-fail/deny_empty_default.rs new file mode 100644 index 000000000..fa5c0d0d6 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/deny_empty_default.rs @@ -0,0 +1,12 @@ +#[macro_use] +extern crate derive_builder; + +// deny `#[builder(default = "")]`, because we don't want to define a meaning (yet)! :-) +#[allow(dead_code)] +#[derive(Builder)] +struct Lorem { + #[builder(default = "")] + ipsum: String, +} + +fn main() {} diff --git a/vendor/derive_builder/tests/compile-fail/deny_empty_default.stderr b/vendor/derive_builder/tests/compile-fail/deny_empty_default.stderr new file mode 100644 index 000000000..df1319471 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/deny_empty_default.stderr @@ -0,0 +1,5 @@ +error: Unknown literal value `` + --> $DIR/deny_empty_default.rs:8:25 + | +8 | #[builder(default = "")] + | ^^ diff --git a/vendor/derive_builder/tests/compile-fail/private_build_fn.rs b/vendor/derive_builder/tests/compile-fail/private_build_fn.rs new file mode 100644 index 000000000..4ee0222d9 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_build_fn.rs @@ -0,0 +1,30 @@ +#[macro_use] +extern crate derive_builder; + +mod container { + /// `LoremBuilder` should be accessible outside the module, but its + /// build method should not be. + #[derive(Debug, Default, Builder)] + #[builder(default, public, build_fn(private))] + pub struct Lorem { + foo: usize, + bar: String, + } + + impl LoremBuilder { + /// Create a `Lorem` + pub fn my_build(&self) -> Lorem { + self.build().expect("All good") + } + } +} + +fn main() { + use container::{Lorem, LoremBuilder}; + + let lorem1 = LoremBuilder::default().my_build(); + + let lorem2 = LoremBuilder::default().build().unwrap(); + + println!("{:?} vs {:?}", lorem1, lorem2); +} diff --git a/vendor/derive_builder/tests/compile-fail/private_build_fn.stderr b/vendor/derive_builder/tests/compile-fail/private_build_fn.stderr new file mode 100644 index 000000000..e74211557 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_build_fn.stderr @@ -0,0 +1,16 @@ +warning: unused import: `Lorem` + --> tests/compile-fail/private_build_fn.rs:23:21 + | +23 | use container::{Lorem, LoremBuilder}; + | ^^^^^ + | + = note: `#[warn(unused_imports)]` on by default + +error[E0624]: associated function `build` is private + --> tests/compile-fail/private_build_fn.rs:27:42 + | +7 | #[derive(Debug, Default, Builder)] + | ------- private associated function defined here +... +27 | let lorem2 = LoremBuilder::default().build().unwrap(); + | ^^^^^ private associated function diff --git a/vendor/derive_builder/tests/compile-fail/private_builder.rs b/vendor/derive_builder/tests/compile-fail/private_builder.rs new file mode 100644 index 000000000..cd13e52d5 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_builder.rs @@ -0,0 +1,23 @@ +#[macro_use] +extern crate derive_builder; + +pub mod foo { + /// The builder struct's declaration of privacy should override the field's + /// attempt to be public later on. + #[derive(Debug, PartialEq, Default, Builder, Clone)] + #[builder(private, setter(into))] + pub struct Lorem { + pub private: String, + #[builder(public)] + pub public: String, + } +} + +fn main() { + let x = foo::LoremBuilder::default() + .public("Hello") + .build() + .unwrap(); + + assert_eq!(x.public, "Hello".to_string()); +} diff --git a/vendor/derive_builder/tests/compile-fail/private_builder.stderr b/vendor/derive_builder/tests/compile-fail/private_builder.stderr new file mode 100644 index 000000000..6684ac28c --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_builder.stderr @@ -0,0 +1,21 @@ +error[E0603]: struct `LoremBuilder` is private + --> tests/compile-fail/private_builder.rs:17:18 + | +17 | let x = foo::LoremBuilder::default() + | ^^^^^^^^^^^^ private struct + | +note: the struct `LoremBuilder` is defined here + --> tests/compile-fail/private_builder.rs:7:41 + | +7 | #[derive(Debug, PartialEq, Default, Builder, Clone)] + | ^^^^^^^ + = note: this error originates in the derive macro `Builder` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0624]: associated function `build` is private + --> tests/compile-fail/private_builder.rs:19:10 + | +7 | #[derive(Debug, PartialEq, Default, Builder, Clone)] + | ------- private associated function defined here +... +19 | .build() + | ^^^^^ private associated function diff --git a/vendor/derive_builder/tests/compile-fail/private_fields.rs b/vendor/derive_builder/tests/compile-fail/private_fields.rs new file mode 100644 index 000000000..74f074df1 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_fields.rs @@ -0,0 +1,26 @@ +#[macro_use] +extern crate derive_builder; + +/// This builder is in an inner module to make sure private fields aren't accessible +/// from the `main` function. +mod inner { + /// The `LoremBuilder` struct will have private fields for `ipsum` and `dolor`, and + /// a public `sit` field. + #[derive(Debug, Builder)] + #[builder(field(private), setter(into))] + pub struct Lorem { + ipsum: String, + dolor: u16, + #[builder(field(public))] + sit: bool, + } +} + +fn main() { + use inner::LoremBuilder; + + let mut lorem = LoremBuilder::default(); + lorem.dolor(15u16); + lorem.sit = Some(true); // <-- public + lorem.dolor = Some(0); // <-- private +} diff --git a/vendor/derive_builder/tests/compile-fail/private_fields.stderr b/vendor/derive_builder/tests/compile-fail/private_fields.stderr new file mode 100644 index 000000000..403e89c81 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/private_fields.stderr @@ -0,0 +1,5 @@ +error[E0616]: field `dolor` of struct `LoremBuilder` is private + --> tests/compile-fail/private_fields.rs:25:11 + | +25 | lorem.dolor = Some(0); // <-- private + | ^^^^^ private field diff --git a/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.rs b/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.rs new file mode 100644 index 000000000..7565efe64 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.rs @@ -0,0 +1,25 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(name = "foo"))] +struct Lorem { + ipsum: &'static str, + pub dolor: &'static str, +} + +fn main() { + let x = LoremBuilder::default() + .ipsum("ipsum") + .foo("dolor") + .build() + .unwrap(); + + assert_eq!(x, + Lorem { + ipsum: "ipsum", + dolor: "dolor", + }); +} diff --git a/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.stderr b/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.stderr new file mode 100644 index 000000000..5e2141b1b --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/rename_setter_struct_level.stderr @@ -0,0 +1,11 @@ +error: Unknown field: `name` + --> tests/compile-fail/rename_setter_struct_level.rs:7:18 + | +7 | #[builder(setter(name = "foo"))] + | ^^^^ + +error[E0433]: failed to resolve: use of undeclared type `LoremBuilder` + --> tests/compile-fail/rename_setter_struct_level.rs:14:13 + | +14 | let x = LoremBuilder::default() + | ^^^^^^^^^^^^ use of undeclared type `LoremBuilder` diff --git a/vendor/derive_builder/tests/compile-fail/vis_conflict.rs b/vendor/derive_builder/tests/compile-fail/vis_conflict.rs new file mode 100644 index 000000000..68e38a417 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/vis_conflict.rs @@ -0,0 +1,21 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Builder)] +#[builder(public, vis = "pub(crate)")] +pub struct Example { + #[builder(public, private)] + field: String, +} + +#[derive(Builder)] +#[builder(public, vis = "pub(crate)", build_fn(private, public))] +pub struct SecondExample { + #[builder(private, vis = "pub")] + a_field: String, +} + +fn main() { + ExampleBuilder::default().build(); + SecondExampleBuilder::default().build(); +} diff --git a/vendor/derive_builder/tests/compile-fail/vis_conflict.stderr b/vendor/derive_builder/tests/compile-fail/vis_conflict.stderr new file mode 100644 index 000000000..c8c2ed823 --- /dev/null +++ b/vendor/derive_builder/tests/compile-fail/vis_conflict.stderr @@ -0,0 +1,41 @@ +error: `public` and `private` cannot be used together + --> tests/compile-fail/vis_conflict.rs:7:15 + | +7 | #[builder(public, private)] + | ^^^^^^ + +error: `vis="..."` cannot be used with `public` or `private` + --> tests/compile-fail/vis_conflict.rs:5:25 + | +5 | #[builder(public, vis = "pub(crate)")] + | ^^^^^^^^^^^^ + +error: `public` and `private` cannot be used together + --> tests/compile-fail/vis_conflict.rs:12:57 + | +12 | #[builder(public, vis = "pub(crate)", build_fn(private, public))] + | ^^^^^^ + +error: `vis="..."` cannot be used with `public` or `private` + --> tests/compile-fail/vis_conflict.rs:14:30 + | +14 | #[builder(private, vis = "pub")] + | ^^^^^ + +error: `vis="..."` cannot be used with `public` or `private` + --> tests/compile-fail/vis_conflict.rs:12:25 + | +12 | #[builder(public, vis = "pub(crate)", build_fn(private, public))] + | ^^^^^^^^^^^^ + +error[E0433]: failed to resolve: use of undeclared type `ExampleBuilder` + --> tests/compile-fail/vis_conflict.rs:19:5 + | +19 | ExampleBuilder::default().build(); + | ^^^^^^^^^^^^^^ use of undeclared type `ExampleBuilder` + +error[E0433]: failed to resolve: use of undeclared type `SecondExampleBuilder` + --> tests/compile-fail/vis_conflict.rs:20:5 + | +20 | SecondExampleBuilder::default().build(); + | ^^^^^^^^^^^^^^^^^^^^ use of undeclared type `SecondExampleBuilder` diff --git a/vendor/derive_builder/tests/compiletests.rs b/vendor/derive_builder/tests/compiletests.rs new file mode 100644 index 000000000..5c43973ca --- /dev/null +++ b/vendor/derive_builder/tests/compiletests.rs @@ -0,0 +1,12 @@ +#![cfg(compiletests)] + +extern crate rustversion; +extern crate trybuild; + +#[rustversion::stable(1.59)] +#[test] +fn compile_test() { + let t = trybuild::TestCases::new(); + t.pass("tests/run-pass/*.rs"); + t.compile_fail("tests/compile-fail/*.rs"); +} diff --git a/vendor/derive_builder/tests/custom_constructor.rs b/vendor/derive_builder/tests/custom_constructor.rs new file mode 100644 index 000000000..b4daabb0a --- /dev/null +++ b/vendor/derive_builder/tests/custom_constructor.rs @@ -0,0 +1,52 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Eq, Builder)] +#[builder(custom_constructor, build_fn(private, name = "fallible_build"))] +struct Request { + url: &'static str, + username: &'static str, + #[builder(default, setter(into))] + password: Option<&'static str>, +} + +impl RequestBuilder { + pub fn new(url: &'static str, username: &'static str) -> Self { + Self { + url: Some(url), + username: Some(username), + ..Self::create_empty() + } + } + + pub fn build(&self) -> Request { + self.fallible_build() + .expect("All required fields set upfront") + } +} + +#[test] +fn new_then_build_succeeds() { + assert_eq!( + RequestBuilder::new("...", "!!!").build(), + Request { + url: "...", + username: "!!!", + password: None + } + ); +} + +#[test] +fn new_then_set_succeeds() { + assert_eq!( + RequestBuilder::new("...", "!!!").password("test").build(), + Request { + url: "...", + username: "!!!", + password: Some("test") + } + ); +} diff --git a/vendor/derive_builder/tests/custom_default.rs b/vendor/derive_builder/tests/custom_default.rs new file mode 100644 index 000000000..8fd6d215f --- /dev/null +++ b/vendor/derive_builder/tests/custom_default.rs @@ -0,0 +1,138 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +mod field_level { + use derive_builder::UninitializedFieldError; + #[derive(Debug, PartialEq, Default, Builder, Clone)] + struct Lorem { + required: String, + #[builder(default)] + explicit_default: String, + #[builder(default = "\"foo\".to_string()")] + escaped_default: String, + #[builder(default = r#"format!("Hello {}!", "World")"#)] + raw_default: String, + #[builder(default = r#"format!("{}-{}-{}-{}", + Clone::clone(self.required + .as_ref() + .ok_or_else(|| UninitializedFieldError::new("required"))?), + match self.explicit_default { Some(ref x) => x, None => "EMPTY" }, + self.escaped_default.as_ref().map(|x| x.as_ref()).unwrap_or("EMPTY"), + if let Some(ref x) = self.raw_default { x } else { "EMPTY" })"#)] + computed_default: String, + } + + #[test] + fn error_if_uninitialized() { + let error = LoremBuilder::default().build().unwrap_err(); + assert_eq!(&error.to_string(), "`required` must be initialized"); + } + + #[test] + fn custom_default() { + let x = LoremBuilder::default() + .required("ipsum".to_string()) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + required: "ipsum".to_string(), + explicit_default: "".to_string(), + escaped_default: "foo".to_string(), + raw_default: "Hello World!".to_string(), + computed_default: "ipsum-EMPTY-EMPTY-EMPTY".to_string(), + } + ); + } + + #[test] + fn builder_test() { + let x = LoremBuilder::default() + .required("ipsum".to_string()) + .explicit_default("lorem".to_string()) + .escaped_default("dolor".to_string()) + .raw_default("sit".to_string()) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + required: "ipsum".to_string(), + explicit_default: "lorem".to_string(), + escaped_default: "dolor".to_string(), + raw_default: "sit".to_string(), + computed_default: "ipsum-lorem-dolor-sit".to_string(), + } + ); + } +} + +mod struct_level { + #[derive(Debug, Clone, PartialEq, Eq, Builder)] + #[builder(default = "explicit_default()")] + struct Lorem { + #[builder(default = "true")] + overwritten: bool, + not_type_default: Option<&'static str>, + } + + fn explicit_default() -> Lorem { + Lorem { + overwritten: false, + not_type_default: Some("defined on struct-level"), + } + } + + #[derive(Debug, Clone, PartialEq, Eq, Builder)] + #[builder(default)] + struct Ipsum { + not_type_default: Option<u16>, + also_custom: bool, + is_type_default: String, + } + + impl Default for Ipsum { + fn default() -> Self { + Ipsum { + not_type_default: Some(20), + also_custom: true, + is_type_default: Default::default(), + } + } + } + + #[test] + fn explicit_defaults_are_equal() { + let lorem = LoremBuilder::default().build().unwrap(); + + assert_eq!( + lorem, + Lorem { + overwritten: true, + ..explicit_default() + } + ); + } + + #[test] + fn implicit_defaults_are_equal() { + let ipsum = IpsumBuilder::default().build().unwrap(); + + assert_eq!(ipsum, Ipsum::default()); + } + + #[test] + fn overrides_work() { + let ipsum = IpsumBuilder::default() + .not_type_default(None) + .build() + .expect("Struct-level default makes all fields optional"); + + assert_eq!(ipsum.not_type_default, None); + } +} diff --git a/vendor/derive_builder/tests/derive_trait.rs b/vendor/derive_builder/tests/derive_trait.rs new file mode 100644 index 000000000..0bb986d66 --- /dev/null +++ b/vendor/derive_builder/tests/derive_trait.rs @@ -0,0 +1,25 @@ +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, Default, Clone)] +struct NotPartialEq(String); + +#[derive(Debug, Clone, Builder)] +#[builder(derive(Debug, PartialEq, Eq))] +struct Lorem { + foo: u8, + + /// This type doesn't have `PartialEq` support, but that's fine + /// since we don't want it in the builder. + #[builder(setter(skip))] + excluded: NotPartialEq, +} + +#[test] +fn defaults() { + // This macro requires that the two sides implement `PartialEq` AND `Debug`, + // so this one line is testing that the requested traits were really generated. + assert_eq!(LoremBuilder::default(), LoremBuilder::default()); +} diff --git a/vendor/derive_builder/tests/forward_allow_attr.rs b/vendor/derive_builder/tests/forward_allow_attr.rs new file mode 100644 index 000000000..768269451 --- /dev/null +++ b/vendor/derive_builder/tests/forward_allow_attr.rs @@ -0,0 +1,24 @@ +#![deny(non_snake_case)] + +#[macro_use] +extern crate derive_builder; + +#[derive(Builder)] +// If this attribute is not forwarded to both the struct and the impl block, there would +// be a compile error on either the field or the setter method name. Therefore, forwarding +// is working as-expected if this test compiles. +#[allow(non_snake_case)] +pub struct Example { + aPascalName: &'static str, +} + +fn main() { + assert_eq!( + ExampleBuilder::default() + .aPascalName("hello") + .build() + .unwrap() + .aPascalName, + "hello" + ); +} diff --git a/vendor/derive_builder/tests/forward_serde_attrs.rs b/vendor/derive_builder/tests/forward_serde_attrs.rs new file mode 100644 index 000000000..2ba7bcf80 --- /dev/null +++ b/vendor/derive_builder/tests/forward_serde_attrs.rs @@ -0,0 +1,29 @@ +#[macro_use] +extern crate derive_builder; +extern crate serde; +extern crate serde_json; + +#[derive(Builder)] +#[builder(setter(into), derive(serde::Serialize))] +#[builder_struct_attr(serde(rename_all = "camelCase"))] +#[allow(dead_code)] +struct Example { + first_name: String, + middle_name: String, + #[builder_field_attr(serde(rename = "familyName"))] + last_name: String, +} + +#[test] +fn serialize_builder() { + assert_eq!( + serde_json::to_string( + &ExampleBuilder::default() + .first_name("Jane") + .middle_name("Alice") + .last_name("Doe"), + ) + .unwrap(), + r#"{"firstName":"Jane","middleName":"Alice","familyName":"Doe"}"# + ); +} diff --git a/vendor/derive_builder/tests/generic_structs.rs b/vendor/derive_builder/tests/generic_structs.rs new file mode 100644 index 000000000..f5119f55c --- /dev/null +++ b/vendor/derive_builder/tests/generic_structs.rs @@ -0,0 +1,59 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +use std::clone::Clone; +use std::fmt::Display; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Generic<T: Display> +where + T: Clone, +{ + ipsum: &'static str, + pub dolor: T, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +pub struct GenericReference<'a, T: 'a + Default> +where + T: Display, +{ + pub bar: Option<&'a T>, +} + +#[test] +fn error_if_uninitialized() { + let error = GenericBuilder::<String>::default().build().unwrap_err(); + assert_eq!(&error.to_string(), "`ipsum` must be initialized"); +} + +#[test] +fn generic_builder() { + let x = GenericBuilder::default() + .ipsum("Generic") + .dolor(true) + .build() + .unwrap(); + + assert_eq!( + x, + Generic { + ipsum: "Generic".into(), + dolor: true, + } + ); +} + +#[test] +fn generic_reference_builder() { + static BAR: u32 = 42; + + let x = GenericReferenceBuilder::<'static, u32>::default() + .bar(Some(&BAR)) + .build() + .unwrap(); + + assert_eq!(x, GenericReference { bar: Some(&BAR) }); +} diff --git a/vendor/derive_builder/tests/generic_with_default.rs b/vendor/derive_builder/tests/generic_with_default.rs new file mode 100644 index 000000000..81a5eaa23 --- /dev/null +++ b/vendor/derive_builder/tests/generic_with_default.rs @@ -0,0 +1,38 @@ +#[macro_use] +extern crate derive_builder; +#[macro_use] +extern crate pretty_assertions; + +/// Struct taken from `@shockham/caper` to make sure we emit the correct +/// code for struct-level defaults in tandem with generics. +#[derive(Builder, Clone, PartialEq)] +#[builder(default)] +pub struct RenderItem<T: Default> { + /// The vertices representing this items mesh + pub vertices: Vec<()>, + /// Whether the item is active/should be rendered + pub active: bool, + /// The name of the RenderItem for lookup + pub name: String, + /// Tag Type for grouping similar items + pub tag: T, +} + +impl<T: Default> Default for RenderItem<T> { + fn default() -> Self { + RenderItem { + vertices: Default::default(), + active: true, + name: "ri".into(), + tag: Default::default(), + } + } +} + +#[test] +fn create_with_string() { + let ri: RenderItem<String> = RenderItemBuilder::default().build().unwrap(); + assert_eq!(ri.tag, ""); + assert_eq!(ri.name, "ri"); + assert!(ri.active); +} diff --git a/vendor/derive_builder/tests/ignore/no_std.rs b/vendor/derive_builder/tests/ignore/no_std.rs new file mode 100644 index 000000000..d31f87f23 --- /dev/null +++ b/vendor/derive_builder/tests/ignore/no_std.rs @@ -0,0 +1,87 @@ +//! Compile behavior test for derive_builder on no_std. Unfortunately, this has broken +//! too many times due to changes in requirements for no_std, and therefore this test +//! is no longer part of the required nightly pass. + +// requires nightly toolchain! +// +// compile-flags:-C panic=abort +#![no_std] +#![feature(alloc, allocator_api, lang_items, start, core_intrinsics, oom)] +#![allow(dead_code)] +use core::intrinsics; +use core::panic::PanicInfo; + + +// Pull in the system libc library for what crt0.o likely requires. +// extern crate libc; + +#[macro_use] +extern crate derive_builder; +extern crate alloc; + +#[derive(Builder)] +#[builder(no_std)] +struct IgnoreEmptyStruct {} + +#[derive(Builder, PartialEq, Debug)] +#[builder(no_std)] +struct Foo { + #[builder(default)] + defaulted: u32, + #[builder(setter(skip), try_setter)] + skipped: u32, +} + +fn main() { + let foo = FooBuilder::default() + .build() + .unwrap(); + + assert_eq!(foo, Foo { + defaulted: 0, + skipped: 0, + }) +} + +/////////////////////////////////////////////////////////////// +// some no_std-boilerplate +// from https://doc.rust-lang.org/book/no-stdlib.html +/////////////////////////////////////////////////////////////// + +// These functions and traits are used by the compiler, but not +// for a bare-bones hello world. These are normally +// provided by libstd. +#[lang = "eh_personality"] +#[no_mangle] +pub extern fn eh_personality() {} + +// This function may be needed based on the compilation target. +#[lang = "eh_unwind_resume"] +#[no_mangle] +pub extern fn rust_eh_unwind_resume() { +} + +#[panic_handler] +#[no_mangle] +fn panic(_info: &PanicInfo) -> ! { + unsafe { intrinsics::abort() } +} + +#[lang = "oom"] +#[no_mangle] +pub extern fn rust_oom(_: core::alloc::Layout) -> ! { + unsafe { intrinsics::abort() } +} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn _Unwind_Resume() -> ! { + unsafe { intrinsics::abort() } +} + +// Entry point for this program +#[start] +fn start(_argc: isize, _argv: *const *const u8) -> isize { + main(); + 0 +} diff --git a/vendor/derive_builder/tests/lifetime.rs b/vendor/derive_builder/tests/lifetime.rs new file mode 100644 index 000000000..13f2a08e2 --- /dev/null +++ b/vendor/derive_builder/tests/lifetime.rs @@ -0,0 +1,22 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Lorem<'a> { + ipsum: &'a str, +} + +#[test] +fn error_if_uninitialized() { + let error = LoremBuilder::default().build().unwrap_err(); + assert_eq!(&error.to_string(), "`ipsum` must be initialized"); +} + +#[test] +fn builder_test() { + let x = LoremBuilder::default().ipsum("ipsum").build().unwrap(); + + assert_eq!(x, Lorem { ipsum: "ipsum" }); +} diff --git a/vendor/derive_builder/tests/run-pass/attributes.rs b/vendor/derive_builder/tests/run-pass/attributes.rs new file mode 100644 index 000000000..46a6fd8f3 --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/attributes.rs @@ -0,0 +1,22 @@ +#[macro_use] +extern crate derive_builder; + +/// This is a doc comment for the struct +#[warn(missing_docs)] +#[allow(non_snake_case, dead_code)] +#[derive(Builder)] +struct Lorem { + /// This is a doc comment for a field + field_with_doc_comment: String, + #[allow(missing_docs)] + undocumented: String, + #[allow(non_snake_case)] + CamelCase: i32, + #[cfg(target_os = "macos")] + mac_only: bool, + #[allow(non_snake_case)] + #[cfg(target_os = "linux")] + LinuxOnly: (), +} + +fn main() { } diff --git a/vendor/derive_builder/tests/run-pass/crate_alias.rs b/vendor/derive_builder/tests/run-pass/crate_alias.rs new file mode 100644 index 000000000..d2e6b473b --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/crate_alias.rs @@ -0,0 +1,24 @@ +//! Test that an alias of derive_builder is valid in #[builder(crate = "...")] +//! +//! This test is imperfect, as it still passes without setting `crate = "..."`. +//! This is likely because `derive_builder` is automatically present in 2018 +//! without needing the extern crate line. +//! +//! The test will fail if an incorrect alias is used, so it adds limited value. + +#[macro_use] +extern crate derive_builder as db; + +#[derive(Builder)] +#[builder(crate = "db")] +struct AliasedCrate { + #[builder(setter(into))] + lorem: String, +} + +fn main() { + AliasedCrateBuilder::default() + .lorem("hello") + .build() + .unwrap(); +} diff --git a/vendor/derive_builder/tests/run-pass/custom_error_default.rs b/vendor/derive_builder/tests/run-pass/custom_error_default.rs new file mode 100644 index 000000000..da0d8f62a --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/custom_error_default.rs @@ -0,0 +1,49 @@ +//! This test ensures custom errors don't need a conversion from `UninitializedFieldError` +//! if uninitialized fields are impossible. + +#[macro_use] +extern crate derive_builder; + +#[derive(Default, Builder)] +#[builder(default, build_fn(validate = "check_person", error = "Error"))] +struct Person { + name: String, + age: u16, +} + +/// An error that deliberately doesn't have `impl From<UninitializedFieldError>`; as long +/// as `PersonBuilder` uses `Person::default` then missing field errors are never possible. +enum Error { + UnpopularName(String), + UnrealisticAge(u16), +} + +fn check_age_realistic(age: u16) -> Result<(), Error> { + if age > 150 { + Err(Error::UnrealisticAge(age)) + } else { + Ok(()) + } +} + +fn check_name_popular(name: &str) -> Result<(), Error> { + if name.starts_with('B') { + Err(Error::UnpopularName(name.to_string())) + } else { + Ok(()) + } +} + +fn check_person(builder: &PersonBuilder) -> Result<(), Error> { + if let Some(age) = &builder.age { + check_age_realistic(*age)?; + } + + if let Some(name) = &builder.name { + check_name_popular(name)?; + } + + Ok(()) +} + +fn main() {} diff --git a/vendor/derive_builder/tests/run-pass/custom_types.rs b/vendor/derive_builder/tests/run-pass/custom_types.rs new file mode 100644 index 000000000..2b4f999e2 --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/custom_types.rs @@ -0,0 +1,30 @@ +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +struct Unit; + +type Clone = Unit; +type Into = Unit; +type Option = Unit; +type Result = Unit; +type Some = Unit; +type String = Unit; + +impl core::fmt::Debug for Unit { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "()") + } +} + +impl core::fmt::Display for Unit { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "()") + } +} + +#[derive(Builder)] +struct IgnoreEmptyStruct {} + +fn main() { } diff --git a/vendor/derive_builder/tests/run-pass/empty_struct.rs b/vendor/derive_builder/tests/run-pass/empty_struct.rs new file mode 100644 index 000000000..f346c6872 --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/empty_struct.rs @@ -0,0 +1,8 @@ +#[macro_use] +extern crate derive_builder; + +#[allow(dead_code)] +#[derive(Builder)] +struct IgnoreEmptyStruct {} + +fn main() { } diff --git a/vendor/derive_builder/tests/run-pass/multiple_derives.rs b/vendor/derive_builder/tests/run-pass/multiple_derives.rs new file mode 100644 index 000000000..8379340df --- /dev/null +++ b/vendor/derive_builder/tests/run-pass/multiple_derives.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate derive_builder; + +#[allow(dead_code)] +#[derive(Builder)] +struct Foo { + lorem: bool, +} + +#[allow(dead_code)] +#[derive(Builder)] +struct Bar { + ipsum: bool, +} + +fn main() { } diff --git a/vendor/derive_builder/tests/setter_custom.rs b/vendor/derive_builder/tests/setter_custom.rs new file mode 100644 index 000000000..3a3d38498 --- /dev/null +++ b/vendor/derive_builder/tests/setter_custom.rs @@ -0,0 +1,86 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(skip = "false"), default)] +struct SetterCustom { + #[builder(setter(custom = "true"))] + setter_custom_by_explicit_opt_in: u32, + #[builder(setter(custom))] + setter_custom_shorthand: u32, + #[builder(setter(custom = "false"))] + setter_custom_by_explicit_opt_out: u32, + #[builder(setter(custom = "true"), default = "4")] + setter_custom_with_explicit_default: u32, + #[builder(setter(custom = "true", strip_option))] + setter_custom_with_strip_option: Option<u32>, +} + +// compile test +#[allow(dead_code)] +impl SetterCustomBuilder { + // only possible if setter was skipped + fn setter_custom_by_explicit_opt_in(&mut self) -> &mut Self { + self.setter_custom_by_explicit_opt_in = Some(1); + self + } + + // only possible if setter was skipped + fn setter_custom_shorthand(&mut self) -> &mut Self { + self.setter_custom_shorthand = Some(2); + self + } + + // only possible if setter was skipped + fn setter_custom_with_explicit_default(&mut self) -> &mut Self { + self.setter_custom_with_explicit_default = Some(43); + self + } + + // only possible if setter was skipped + fn setter_custom_with_strip_option(&mut self) -> &mut Self { + self.setter_custom_with_strip_option = Some(Some(6)); + self + } +} + +#[test] +fn setter_custom_defaults() { + let x: SetterCustom = SetterCustomBuilder::default().build().unwrap(); + + assert_eq!( + x, + SetterCustom { + setter_custom_by_explicit_opt_in: 0, + setter_custom_shorthand: 0, + setter_custom_by_explicit_opt_out: 0, + setter_custom_with_explicit_default: 4, + setter_custom_with_strip_option: None, + } + ); +} + +#[test] +fn setter_custom_setters_called() { + let x: SetterCustom = SetterCustomBuilder::default() + .setter_custom_by_explicit_opt_in() // set to 1 + .setter_custom_shorthand() // set to 2 + .setter_custom_by_explicit_opt_out(42) + .setter_custom_with_explicit_default() // set to 43 + .setter_custom_with_strip_option() // set to 6 + .build() + .unwrap(); + + assert_eq!( + x, + SetterCustom { + setter_custom_by_explicit_opt_in: 1, + setter_custom_shorthand: 2, + setter_custom_by_explicit_opt_out: 42, + setter_custom_with_explicit_default: 43, + setter_custom_with_strip_option: Some(6) + } + ); +} diff --git a/vendor/derive_builder/tests/setter_extend.rs b/vendor/derive_builder/tests/setter_extend.rs new file mode 100644 index 000000000..496c656d3 --- /dev/null +++ b/vendor/derive_builder/tests/setter_extend.rs @@ -0,0 +1,160 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +use std::collections::HashMap; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Lorem { + #[builder(setter(each = "foo_append"))] + foo: String, + #[builder(setter(each = "bar"))] + bars: Vec<String>, + #[builder(setter(each = "baz"))] + bazes: HashMap<String, i32>, + #[builder(setter(strip_option, each = "qux"))] + quxes: Option<Vec<String>>, + #[builder(setter(strip_option, each = "quux"))] + quuxes: Option<HashMap<String, i32>>, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(pattern = "mutable")] +struct Ipsum { + #[builder(setter(each(name = "foo_append")))] + foo: String, + #[builder(setter(each(name = "bar")))] + bars: Vec<String>, + #[builder(setter(each(name = "baz")))] + bazes: HashMap<String, i32>, + #[builder(setter(strip_option, each = "qux"))] + quxes: Option<Vec<String>>, + #[builder(setter(strip_option, each = "quux"))] + quuxes: Option<HashMap<String, i32>>, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder] +struct Dolor { + #[builder(setter(each(name = "foo_append")))] + foo: String, + #[builder(setter(each(name = "bar", into)))] + bars: Vec<String>, + #[builder(setter(each(name = "baz")))] + bazes: HashMap<String, i32>, +} + +#[test] +fn extend_field() { + let x = LoremBuilder::default() + .foo("foo".into()) + .bar("bar".into()) + .bar("bar bar".into()) + .bar("bar bar bar".into()) + .foo_append('-') + .baz(("baz".into(), 1)) + .baz(("bazz".into(), 2)) + .baz(("bazzz".into(), 3)) + .foo_append("foo") + .qux("qux".into()) + .qux("qux qux".into()) + .quux(("quux".into(), 1)) + .quux(("quuxx".into(), 2)) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + foo: "foo-foo".into(), + bars: vec!["bar".into(), "bar bar".into(), "bar bar bar".into()], + bazes: vec![("baz".into(), 1), ("bazz".into(), 2), ("bazzz".into(), 3)] + .into_iter() + .collect(), + quxes: Some(vec!["qux".into(), "qux qux".into()]), + quuxes: Some( + vec![("quux".into(), 1), ("quuxx".into(), 2)] + .into_iter() + .collect() + ), + } + ); +} + +#[test] +fn extend_field_into() { + let x = DolorBuilder::default() + .foo("foo".into()) + .bar("bar") + .bar("bar bar") + .bar("bar bar bar") + .foo_append('-') + .baz(("baz".into(), 1)) + .baz(("bazz".into(), 2)) + .baz(("bazzz".into(), 3)) + .foo_append("foo") + .build() + .unwrap(); + + assert_eq!( + x, + Dolor { + foo: "foo-foo".into(), + bars: vec!["bar".into(), "bar bar".into(), "bar bar bar".into()], + bazes: vec![("baz".into(), 1), ("bazz".into(), 2), ("bazzz".into(), 3)] + .into_iter() + .collect(), + } + ); +} + +#[test] +fn extend_field_mutable() { + let x = IpsumBuilder::default() + .foo("foo".into()) + .bar("bar".into()) + .bar("bar bar".into()) + .bar("bar bar bar".into()) + .foo_append('-') + .baz(("baz".into(), 1)) + .baz(("bazz".into(), 2)) + .baz(("bazzz".into(), 3)) + .foo_append("foo") + .qux("qux".into()) + .qux("qux qux".into()) + .quux(("quux".into(), 1)) + .quux(("quuxx".into(), 2)) + .build() + .unwrap(); + + assert_eq!( + x, + Ipsum { + foo: "foo-foo".into(), + bars: vec!["bar".into(), "bar bar".into(), "bar bar bar".into()], + bazes: vec![("baz".into(), 1), ("bazz".into(), 2), ("bazzz".into(), 3)] + .into_iter() + .collect(), + quxes: Some(vec!["qux".into(), "qux qux".into()]), + quuxes: Some( + vec![("quux".into(), 1), ("quuxx".into(), 2)] + .into_iter() + .collect() + ), + } + ); +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(skip))] +struct Sit { + #[builder(setter(each(name = "foo")))] + foos: Vec<i32>, +} + +#[test] +fn extend_field_enabled() { + let x = SitBuilder::default().foo(1).foo(2).build().unwrap(); + assert_eq!(x, Sit { foos: vec![1, 2] }); +} diff --git a/vendor/derive_builder/tests/setter_into.rs b/vendor/derive_builder/tests/setter_into.rs new file mode 100644 index 000000000..b73852d88 --- /dev/null +++ b/vendor/derive_builder/tests/setter_into.rs @@ -0,0 +1,35 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Lorem { + #[builder(setter(into))] + foo: String, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(into))] +struct Ipsum { + foo: u32, +} + +#[test] +fn generic_field() { + let x = LoremBuilder::default().foo("foo").build().unwrap(); + + assert_eq!( + x, + Lorem { + foo: "foo".to_string() + } + ); +} + +#[test] +fn generic_struct() { + let x = IpsumBuilder::default().foo(42u8).build().unwrap(); + + assert_eq!(x, Ipsum { foo: 42u32 }); +} diff --git a/vendor/derive_builder/tests/setter_name.rs b/vendor/derive_builder/tests/setter_name.rs new file mode 100644 index 000000000..e1ddade84 --- /dev/null +++ b/vendor/derive_builder/tests/setter_name.rs @@ -0,0 +1,29 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(prefix = "with"))] +struct Lorem { + ipsum: &'static str, + #[builder(setter(name = "foo"))] + pub dolor: &'static str, +} + +#[test] +fn renamed_setter() { + let x = LoremBuilder::default() + .with_ipsum("ipsum") + .foo("dolor") + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: "ipsum", + dolor: "dolor", + } + ); +} diff --git a/vendor/derive_builder/tests/setter_pattern.rs b/vendor/derive_builder/tests/setter_pattern.rs new file mode 100644 index 000000000..b4454891e --- /dev/null +++ b/vendor/derive_builder/tests/setter_pattern.rs @@ -0,0 +1,107 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(pattern = "immutable")] +struct Lorem { + immutable: u32, + #[builder(pattern = "mutable")] + mutable_override: u32, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(pattern = "mutable")] +struct Ipsum { + mutable: u32, + #[builder(pattern = "owned")] + owned_override: u32, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(pattern = "owned")] +struct Dolor { + #[builder(pattern = "immutable")] + immutable_override: u32, + owned: u32, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Sit { + default: u32, +} + +type ImmutableSetter<T, U> = fn(&T, U) -> T; +type OwnedSetter<T, U> = fn(T, U) -> T; +type MutableSetter<T, U> = fn(&mut T, U) -> &mut T; + +#[test] +fn mutable_by_default() { + // the setter must have the correct signature + let mutable_setter: MutableSetter<SitBuilder, u32> = SitBuilder::default; + + let mut old = <SitBuilder as Default>::default(); + mutable_setter(&mut old, 42); + assert_eq!(old.default, Some(42)); +} + +#[test] +fn mutable() { + // the setter must have the correct signature + let mutable_setter: MutableSetter<IpsumBuilder, u32> = IpsumBuilder::mutable; + + let mut old = IpsumBuilder::default(); + mutable_setter(&mut old, 42); + assert_eq!(old.mutable, Some(42)); +} + +#[test] +fn mutable_override() { + // the setter must have the correct signature + let mutable_setter: MutableSetter<LoremBuilder, u32> = LoremBuilder::mutable_override; + + let mut old = LoremBuilder::default(); + mutable_setter(&mut old, 42); + assert_eq!(old.mutable_override, Some(42)); +} + +#[test] +fn immutable() { + // the setter must have the correct signature + let immutable_setter: ImmutableSetter<LoremBuilder, u32> = LoremBuilder::immutable; + + let old = LoremBuilder::default(); + let new = immutable_setter(&old, 42); + assert_eq!(new.immutable, Some(42)); +} + +#[test] +fn immutable_override() { + // the setter must have the correct signature + let immutable_setter: ImmutableSetter<DolorBuilder, u32> = DolorBuilder::immutable_override; + + let old = DolorBuilder::default(); + let new = immutable_setter(&old, 42); + assert_eq!(new.immutable_override, Some(42)); +} + +#[test] +fn owned() { + // the setter must have the correct signature + let owned_setter: OwnedSetter<DolorBuilder, u32> = DolorBuilder::owned; + + let old = DolorBuilder::default(); + let new = owned_setter(old, 42); + assert_eq!(new.owned, Some(42)); +} + +#[test] +fn owned_override() { + // the setter must have the correct signature + let owned_setter: OwnedSetter<IpsumBuilder, u32> = IpsumBuilder::owned_override; + + let old = IpsumBuilder::default(); + let new = owned_setter(old, 42); + assert_eq!(new.owned_override, Some(42)); +} diff --git a/vendor/derive_builder/tests/setter_prefix.rs b/vendor/derive_builder/tests/setter_prefix.rs new file mode 100644 index 000000000..2b423c7c7 --- /dev/null +++ b/vendor/derive_builder/tests/setter_prefix.rs @@ -0,0 +1,29 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(prefix = "with"))] +struct Lorem { + ipsum: &'static str, + #[builder(setter(prefix = "set"))] + pub dolor: &'static str, +} + +#[test] +fn prefixed_setters() { + let x = LoremBuilder::default() + .with_ipsum("ipsum") + .set_dolor("dolor") + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: "ipsum", + dolor: "dolor", + } + ); +} diff --git a/vendor/derive_builder/tests/setter_strip_option.rs b/vendor/derive_builder/tests/setter_strip_option.rs new file mode 100644 index 000000000..d502340c6 --- /dev/null +++ b/vendor/derive_builder/tests/setter_strip_option.rs @@ -0,0 +1,64 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +struct Lorem { + #[builder(setter(into))] + full_opt: Option<String>, + #[builder(setter(into, strip_option))] + strip_opt: Option<String>, + #[builder(setter(strip_option))] + strip_opt_i32: Option<i32>, + #[builder(setter(strip_option))] + strip_opt_vec: Option<Vec<i32>>, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(into, strip_option))] +struct Ipsum { + foo: u32, + strip_opt: Option<String>, + #[builder(default)] + strip_opt_with_default: Option<String>, +} + +#[test] +fn generic_field() { + let x = LoremBuilder::default() + .full_opt(Some("foo".to_string())) + .strip_opt("bar") + .strip_opt_i32(32) + .strip_opt_vec(vec![33]) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + full_opt: Some("foo".to_string()), + strip_opt: Some("bar".to_string()), + strip_opt_i32: Some(32), + strip_opt_vec: Some(vec![33]), + } + ); +} + +#[test] +fn generic_struct() { + let x = IpsumBuilder::default() + .foo(42u8) + .strip_opt("bar") + .build() + .unwrap(); + + assert_eq!( + x, + Ipsum { + foo: 42u32, + strip_opt: Some("bar".to_string()), + strip_opt_with_default: None, + } + ); +} diff --git a/vendor/derive_builder/tests/setter_visibility.rs b/vendor/derive_builder/tests/setter_visibility.rs new file mode 100644 index 000000000..999509348 --- /dev/null +++ b/vendor/derive_builder/tests/setter_visibility.rs @@ -0,0 +1,63 @@ +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +pub mod foo { + #[derive(Debug, PartialEq, Default, Builder, Clone)] + #[builder(private, setter(into))] + pub struct Lorem { + pub private: String, + #[builder(public)] + pub public: String, + } + + #[derive(Debug, PartialEq, Default, Builder, Clone)] + #[builder(public, setter(into))] + pub struct Ipsum { + #[builder(private)] + pub private: String, + pub public: String, + } + + #[test] + fn setters_same_module() { + let x = LoremBuilder::default() + .public("Hello") + .private("world!") + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + public: "Hello".into(), + private: "world!".into(), + } + ); + + let y = IpsumBuilder::default() + .public("Hello") + .private("world!") + .build() + .unwrap(); + + assert_eq!( + y, + Ipsum { + public: "Hello".into(), + private: "world!".into(), + } + ); + } +} + +#[test] +fn public_setters_foreign_module() { + let error = foo::IpsumBuilder::default() + .public("Hello") + .build() + .unwrap_err(); + + assert_eq!(&error.to_string(), "`private` must be initialized"); +} diff --git a/vendor/derive_builder/tests/skip-setter.rs b/vendor/derive_builder/tests/skip-setter.rs new file mode 100644 index 000000000..dbb4d62e6 --- /dev/null +++ b/vendor/derive_builder/tests/skip-setter.rs @@ -0,0 +1,138 @@ +// https://github.com/colin-kiegel/rust-derive-builder/issues/15 +#[macro_use] +extern crate pretty_assertions; +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, Clone, PartialEq)] +struct NotDefaultable(String); + +fn new_notdefaultable() -> NotDefaultable { + NotDefaultable("Lorem".to_string()) +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(skip = "false"))] +struct SetterOptOut { + setter_present_by_explicit_default: u32, + #[builder(setter(skip = "true"))] + setter_skipped_by_explicit_opt_out: u32, + #[builder(setter(skip))] + setter_skipped_by_shorthand_opt_out: u32, + #[builder(setter(skip), default = "4")] + setter_skipped_with_explicit_default: u32, +} + +#[derive(Debug, PartialEq, Default, Builder, Clone)] +#[builder(setter(skip))] +struct SetterOptIn { + setter_skipped_by_shorthand_default: u32, + #[builder(setter(skip = false))] // Should be still OK without quotes + setter_present_by_explicit_opt_in: u32, + #[builder(setter)] + setter_present_by_shorthand_opt_in: u32, + #[builder(setter(prefix = "set"))] + setter_present_by_shorthand_opt_in_2: u32, +} + +#[derive(Debug, PartialEq, Builder, Clone)] +#[builder(default, setter(skip))] +struct SetterOptInStructDefault { + setter_skipped_with_struct_default: NotDefaultable, + setter_skipped_with_type_default: u32, +} + +#[derive(Debug, PartialEq, Builder, Clone)] +#[builder(setter(into))] +struct SetterOptInFieldDefault { + #[builder(setter(skip), default = "new_notdefaultable()")] + setter_skipped_with_field_default: NotDefaultable, + + #[builder(default)] + setter_present_by_default: u32, +} + +// compile test +#[allow(dead_code)] +impl SetterOptOut { + // only possible if setter was skipped + fn setter_skipped_by_explicit_opt_out() {} + // only possible if setter was skipped + fn setter_skipped_by_shorthand_opt_out() {} +} + +// compile test +#[allow(dead_code)] +impl SetterOptIn { + // only possible if setter was skipped + fn setter_skipped_by_shorthand_default() {} +} + +impl Default for SetterOptInStructDefault { + fn default() -> Self { + SetterOptInStructDefault { + setter_skipped_with_struct_default: new_notdefaultable(), + setter_skipped_with_type_default: Default::default(), + } + } +} + +#[test] +fn setter_opt_out() { + let x: SetterOptOut = SetterOptOutBuilder::default() + .setter_present_by_explicit_default(42u32) + .build() + .unwrap(); + + assert_eq!( + x, + SetterOptOut { + setter_present_by_explicit_default: 42, + setter_skipped_by_explicit_opt_out: 0, + setter_skipped_by_shorthand_opt_out: 0, + setter_skipped_with_explicit_default: 4, + } + ); +} + +#[test] +fn setter_opt_in() { + let x: SetterOptIn = SetterOptInBuilder::default() + .setter_present_by_explicit_opt_in(47u32) + .setter_present_by_shorthand_opt_in(11u32) + .set_setter_present_by_shorthand_opt_in_2(815u32) + .build() + .unwrap(); + + assert_eq!( + x, + SetterOptIn { + setter_skipped_by_shorthand_default: 0, + setter_present_by_explicit_opt_in: 47, + setter_present_by_shorthand_opt_in: 11, + setter_present_by_shorthand_opt_in_2: 815, + } + ); +} + +#[test] +fn setter_skipped_with_struct_default() { + let x = SetterOptInStructDefaultBuilder::default().build().unwrap(); + + assert_eq!(x, SetterOptInStructDefault::default()); +} + +#[test] +fn setter_skipped_with_field_default() { + let x = SetterOptInFieldDefaultBuilder::default() + .build() + .expect("All fields were defaulted"); + + assert_eq!( + x, + SetterOptInFieldDefault { + setter_skipped_with_field_default: new_notdefaultable(), + setter_present_by_default: Default::default(), + } + ); +} diff --git a/vendor/derive_builder/tests/try_setter.rs b/vendor/derive_builder/tests/try_setter.rs new file mode 100644 index 000000000..28f6a01c0 --- /dev/null +++ b/vendor/derive_builder/tests/try_setter.rs @@ -0,0 +1,87 @@ +#[macro_use] +extern crate derive_builder; + +use std::convert::TryFrom; +use std::net::{AddrParseError, IpAddr}; +use std::str::FromStr; +use std::string::ToString; + +#[derive(Debug, Clone, PartialEq)] +pub struct MyAddr(IpAddr); + +impl From<IpAddr> for MyAddr { + fn from(v: IpAddr) -> Self { + MyAddr(v) + } +} + +impl<'a> TryFrom<&'a str> for MyAddr { + type Error = AddrParseError; + + fn try_from(v: &str) -> Result<Self, Self::Error> { + Ok(MyAddr(v.parse()?)) + } +} + +#[derive(Debug, PartialEq, Builder)] +#[builder(try_setter, setter(into))] +struct Lorem { + pub source: MyAddr, + pub dest: MyAddr, +} + +#[derive(Debug, PartialEq, Builder)] +#[builder(try_setter, setter(into, prefix = "set"))] +struct Ipsum { + pub source: MyAddr, +} + +fn exact_helper() -> Result<Lorem, LoremBuilderError> { + LoremBuilder::default() + .source(IpAddr::from_str("1.2.3.4").unwrap()) + .dest(IpAddr::from_str("0.0.0.0").unwrap()) + .build() +} + +fn try_helper() -> Result<Lorem, LoremBuilderError> { + LoremBuilder::default() + .try_source("1.2.3.4") + .map_err(|e| e.to_string())? + .try_dest("0.0.0.0") + .map_err(|e| e.to_string())? + .build() +} + +#[test] +fn infallible_set() { + let _ = LoremBuilder::default() + .source(IpAddr::from_str("1.2.3.4").unwrap()) + .dest(IpAddr::from_str("0.0.0.0").unwrap()) + .build(); +} + +#[test] +fn fallible_set() { + let mut builder = LoremBuilder::default(); + let try_result = builder.try_source("1.2.3.4"); + let built = try_result + .expect("Passed well-formed address") + .dest(IpAddr::from_str("0.0.0.0").unwrap()) + .build() + .unwrap(); + assert_eq!(built, exact_helper().unwrap()); +} + +#[test] +fn with_helper() { + assert_eq!(exact_helper().unwrap(), try_helper().unwrap()); +} + +#[test] +fn renamed() { + IpsumBuilder::default() + .try_set_source("0.0.0.0") + .unwrap() + .build() + .expect("All fields were provided"); +} diff --git a/vendor/derive_builder/tests/validation.rs b/vendor/derive_builder/tests/validation.rs new file mode 100644 index 000000000..877764281 --- /dev/null +++ b/vendor/derive_builder/tests/validation.rs @@ -0,0 +1,79 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, Clone, Builder, PartialEq, Eq)] +#[builder(build_fn(validate = "LoremBuilder::validate"))] +pub struct Lorem { + /// A percentile. Must be between 0 and 100. + my_effort: u8, + + /// A percentile. Must be less than or equal to `Lorem::my_effort`. + #[builder(default = "40")] + their_effort: u8, + + /// A percentile. Must be between 0 and 100. + rivals_effort: u8, +} + +impl LoremBuilder { + /// Performs bound checks. + fn validate(&self) -> Result<(), String> { + if let Some(ref my_effort) = self.my_effort { + if *my_effort > 100 { + return Err("Don't wear yourself out".to_string()); + } + } + + if let Some(ref their_effort) = self.their_effort { + if *their_effort > 100 { + return Err("The game has changed".to_string()); + } + } + + if let Some(ref rivals_effort) = self.rivals_effort { + if *rivals_effort > 100 { + return Err("Your rival is cheating".to_string()); + } + } + + Ok(()) + } +} + +#[test] +fn out_of_bounds() { + assert_eq!( + &LoremBuilder::default() + .my_effort(120) + .build() + .unwrap_err() + .to_string(), + "Don't wear yourself out" + ); + assert_eq!( + &LoremBuilder::default() + .rivals_effort(120) + .build() + .unwrap_err() + .to_string(), + "Your rival is cheating" + ); +} + +#[test] +fn validation_pass() { + let lorem = LoremBuilder::default() + .my_effort(90) + .rivals_effort(89) + .build() + .expect("All validations should be passing"); + + assert_eq!( + lorem, + Lorem { + my_effort: 90, + rivals_effort: 89, + their_effort: 40, + } + ); +} |