diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/derive_builder/examples | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/derive_builder/examples')
-rw-r--r-- | vendor/derive_builder/examples/channel.rs | 41 | ||||
-rw-r--r-- | vendor/derive_builder/examples/custom_constructor.rs | 74 | ||||
-rw-r--r-- | vendor/derive_builder/examples/custom_defaults.rs | 53 | ||||
-rw-r--r-- | vendor/derive_builder/examples/custom_error.rs | 55 | ||||
-rw-r--r-- | vendor/derive_builder/examples/custom_error_generic.rs | 56 | ||||
-rw-r--r-- | vendor/derive_builder/examples/deny_missing_docs.rs | 23 | ||||
-rw-r--r-- | vendor/derive_builder/examples/doc_example.rs | 14 | ||||
-rw-r--r-- | vendor/derive_builder/examples/readme_example.rs | 24 | ||||
-rw-r--r-- | vendor/derive_builder/examples/validation.rs | 34 |
9 files changed, 374 insertions, 0 deletions
diff --git a/vendor/derive_builder/examples/channel.rs b/vendor/derive_builder/examples/channel.rs new file mode 100644 index 000000000..7c89701b5 --- /dev/null +++ b/vendor/derive_builder/examples/channel.rs @@ -0,0 +1,41 @@ +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +use std::convert::From; + +#[derive(PartialEq, Default, Debug, Clone)] +struct Uuid(i32); +#[derive(PartialEq, Default, Debug, Clone)] +struct Authentication(i32); + +impl From<i32> for Uuid { + fn from(x: i32) -> Uuid { + Uuid(x) + } +} + +impl From<i32> for Authentication { + fn from(x: i32) -> Authentication { + Authentication(x) + } +} + +#[derive(Debug, Default, Builder)] +#[builder(setter(into))] +struct Channel { + id: Uuid, + token: Authentication, + special_info: i32, +} + +fn main() { + let ch = ChannelBuilder::default() + .special_info(42) + .id(0) + .token(5_494_192) + .build() + .unwrap(); + println!("{:?}", ch); +} diff --git a/vendor/derive_builder/examples/custom_constructor.rs b/vendor/derive_builder/examples/custom_constructor.rs new file mode 100644 index 000000000..9d9d6fdda --- /dev/null +++ b/vendor/derive_builder/examples/custom_constructor.rs @@ -0,0 +1,74 @@ +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +#[derive(Debug, Clone)] +pub enum ContentType { + Json, + Xml, +} + +impl Default for ContentType { + fn default() -> Self { + Self::Json + } +} + +#[derive(Debug, Builder)] +#[builder( + custom_constructor, + create_empty = "empty", + build_fn(private, name = "fallible_build") +)] +pub struct ApiClient { + // To make sure `host` and `key` are not changed after creation, tell derive_builder + // to create the fields but not to generate setters. + #[builder(setter(custom))] + host: String, + #[builder(setter(custom))] + key: String, + // uncommenting this field will cause the unit-test below to fail + // baz: String, + #[builder(default)] + content_type: ContentType, +} + +impl ApiClient { + pub fn new(host: impl Into<String>, key: impl Into<String>) -> ApiClientBuilder { + ApiClientBuilder { + host: Some(host.into()), + key: Some(key.into()), + ..ApiClientBuilder::empty() + } + } +} + +impl ApiClientBuilder { + pub fn build(&self) -> ApiClient { + self.fallible_build() + .expect("All required fields were initialized") + } +} + +fn main() { + dbg!(ApiClient::new("hello", "world") + .content_type(ContentType::Xml) + .build()); +} + +#[cfg(test)] +mod tests { + use super::ApiClient; + + /// If any required fields are added to ApiClient and ApiClient::new was not updated, + /// the field will be `None` when this "infallible" build method is called, resulting + /// in a panic. Panicking is appropriate here, since the author of the builder promised + /// the caller that it was safe to call new(...) followed immediately by build(), and + /// the builder author is also the person who can correct the coding error by setting + /// a default for the new property or changing the signature of `new` + #[test] + fn api_client_new_collects_all_required_fields() { + ApiClient::new("hello", "world").build(); + } +} diff --git a/vendor/derive_builder/examples/custom_defaults.rs b/vendor/derive_builder/examples/custom_defaults.rs new file mode 100644 index 000000000..bf493d9e5 --- /dev/null +++ b/vendor/derive_builder/examples/custom_defaults.rs @@ -0,0 +1,53 @@ +#[macro_use] +extern crate derive_builder; + +#[derive(Builder, PartialEq, Debug)] +struct Lorem { + ipsum: String, + #[builder(default = "self.default_dolor()?")] + dolor: String, + #[builder(default = "self.default_sit()?")] + sit: String, + #[builder(setter(skip), default = "self.default_amet()")] + amet: String, +} + +impl LoremBuilder { + fn default_dolor(&self) -> Result<String, String> { + self.ipsum + .clone() + .ok_or_else(|| "ipsum must be initialized to build dolor".to_string()) + } + + fn default_sit(&self) -> Result<String, String> { + match self.ipsum { + Some(ref x) if x.chars().count() > 3 => Ok(format!("sit {}", x)), + _ => Err("ipsum must at least 3 chars to build sit".to_string()), + } + } + + fn default_amet(&self) -> String { + if let Some(ref x) = self.ipsum { + format!("amet {}", x) + } else { + "..nothing there".to_string() + } + } +} + +fn main() { + let x = LoremBuilder::default() + .ipsum("ipsum".to_string()) + .build() + .unwrap(); + + assert_eq!( + x, + Lorem { + ipsum: "ipsum".to_string(), + dolor: "ipsum".to_string(), + sit: "sit ipsum".to_string(), + amet: "amet ipsum".to_string(), + } + ); +} diff --git a/vendor/derive_builder/examples/custom_error.rs b/vendor/derive_builder/examples/custom_error.rs new file mode 100644 index 000000000..409809ac3 --- /dev/null +++ b/vendor/derive_builder/examples/custom_error.rs @@ -0,0 +1,55 @@ +//! This example shows using custom validation with a non-string error type. +//! +//! This relies on how the generated build function is constructed; the validator +//! is invoked in conjunction with the `?` operator, so anything that converts to +//! the generated `FooBuilderError` type is valid. +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +use derive_builder::UninitializedFieldError; +use std::fmt; + +fn validate_age(builder: &ExampleBuilder) -> Result<(), Error> { + match builder.age { + Some(age) if age > 150 => Err(Error::UnrealisticAge(age)), + _ => Ok(()), + } +} + +#[derive(Debug, Builder)] +#[builder(setter(into), build_fn(validate = "validate_age", error = "Error"))] +struct Example { + name: String, + age: usize, +} + +enum Error { + UninitializedField(&'static str), + UnrealisticAge(usize), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::UnrealisticAge(age) => write!(f, "Nobody is {} years old", age), + Self::UninitializedField(field) => write!(f, "Required field '{}' not set", field), + } + } +} + +impl From<UninitializedFieldError> for Error { + fn from(e: UninitializedFieldError) -> Self { + Self::UninitializedField(e.field_name()) + } +} + +fn main() { + let person_err = ExampleBuilder::default() + .name("Jane Doe") + .age(200usize) + .build() + .unwrap_err(); + println!("{}", person_err); +} diff --git a/vendor/derive_builder/examples/custom_error_generic.rs b/vendor/derive_builder/examples/custom_error_generic.rs new file mode 100644 index 000000000..230d53eba --- /dev/null +++ b/vendor/derive_builder/examples/custom_error_generic.rs @@ -0,0 +1,56 @@ +//! This example shows combining generics with custom errors and validation. +//! +//! Note the use of the type parameter in the `#[builder(...)]` attribute. +#![allow(dead_code)] + +#[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: Popular + Clone> { + name: N, + age: u16, +} + +#[derive(Debug)] +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() { + dbg!(PersonBuilder::default() + .name("bill") + .age(71) + .build() + .unwrap_err()); +} diff --git a/vendor/derive_builder/examples/deny_missing_docs.rs b/vendor/derive_builder/examples/deny_missing_docs.rs new file mode 100644 index 000000000..1121a1ec1 --- /dev/null +++ b/vendor/derive_builder/examples/deny_missing_docs.rs @@ -0,0 +1,23 @@ +//! Some people may have `#![deny(missing_docs)]` in their crate. +//! +//! NOTE: This can only be tested in examples, but not integration tests. +#![deny(missing_docs)] + +#[macro_use] +extern crate derive_builder; + +/// Traditional form of communication. +#[derive(Debug, Builder)] +#[builder(setter(into))] +pub struct Letter { + /// Be creative. + pub message: String, +} + +fn main() { + let x = LetterBuilder::default() + .message("Hello World!") + .build() + .unwrap(); + println!("{}", x.message); +} diff --git a/vendor/derive_builder/examples/doc_example.rs b/vendor/derive_builder/examples/doc_example.rs new file mode 100644 index 000000000..43fddbf50 --- /dev/null +++ b/vendor/derive_builder/examples/doc_example.rs @@ -0,0 +1,14 @@ +// NOTE: generate fully expanded version with `cargo expand`. +// +// cargo expand --example doc_example + +#[macro_use] +extern crate derive_builder; + +#[allow(dead_code)] +#[derive(Builder)] +struct Lorem { + ipsum: u32, +} + +fn main() {} diff --git a/vendor/derive_builder/examples/readme_example.rs b/vendor/derive_builder/examples/readme_example.rs new file mode 100644 index 000000000..d227dc1e5 --- /dev/null +++ b/vendor/derive_builder/examples/readme_example.rs @@ -0,0 +1,24 @@ +// NOTE: generate fully expanded version with `cargo expand`. +// +// cargo expand --example readme_example +#![allow(dead_code)] + +#[macro_use] +extern crate derive_builder; + +#[derive(Default, Builder, Debug)] +#[builder(setter(into))] +struct Channel { + token: i32, + special_info: i32, +} + +fn main() { + // builder pattern, go, go, go!... + let ch = ChannelBuilder::default() + .special_info(42u8) + .token(19_124) + .build() + .unwrap(); + println!("{:?}", ch); +} diff --git a/vendor/derive_builder/examples/validation.rs b/vendor/derive_builder/examples/validation.rs new file mode 100644 index 000000000..154b937e0 --- /dev/null +++ b/vendor/derive_builder/examples/validation.rs @@ -0,0 +1,34 @@ +//! This example illustrates the use of `validate` to add a pre-build validation +//! step. + +#[macro_use] +extern crate derive_builder; + +#[derive(Builder, Debug, PartialEq)] +#[builder(build_fn(validate = "Self::validate"))] +struct Lorem { + pub ipsum: u8, +} + +impl LoremBuilder { + /// Check that `Lorem` is putting in the right amount of effort. + fn validate(&self) -> Result<(), String> { + if let Some(ref ipsum) = self.ipsum { + match *ipsum { + i if i < 20 => Err("Try harder".to_string()), + i if i > 100 => Err("You'll tire yourself out".to_string()), + _ => Ok(()), + } + } else { + Ok(()) + } + } +} + +fn main() { + // If we're trying too hard... + let x = LoremBuilder::default().ipsum(120).build().unwrap_err(); + + // .. the build will fail: + assert_eq!(&x.to_string(), "You'll tire yourself out"); +} |