From d1b2d29528b7794b41e66fc2136e395a02f8529b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:59:35 +0200 Subject: Merging upstream version 1.73.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/derive_setters/.cargo-checksum.json | 1 + vendor/derive_setters/Cargo.toml | 38 +++ vendor/derive_setters/README.md | 79 ++++++ vendor/derive_setters/src/lib.rs | 369 +++++++++++++++++++++++++++++ vendor/derive_setters/tests/basics.rs | 156 ++++++++++++ vendor/derive_setters/tests/ref.rs | 90 +++++++ 6 files changed, 733 insertions(+) create mode 100644 vendor/derive_setters/.cargo-checksum.json create mode 100644 vendor/derive_setters/Cargo.toml create mode 100644 vendor/derive_setters/README.md create mode 100644 vendor/derive_setters/src/lib.rs create mode 100644 vendor/derive_setters/tests/basics.rs create mode 100644 vendor/derive_setters/tests/ref.rs (limited to 'vendor/derive_setters') diff --git a/vendor/derive_setters/.cargo-checksum.json b/vendor/derive_setters/.cargo-checksum.json new file mode 100644 index 000000000..6c7f9da8f --- /dev/null +++ b/vendor/derive_setters/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"e18d8d879b61d9a712d4deec14c46903ebc6b71f5ef4f4223b41abba0ed8a3d7","README.md":"0e59b26ffa79747ea62b4cfe58d29f316b260c1b1b84888b39b95c81451cc852","src/lib.rs":"1641aecff4799ee11a8937f716b6e1bbf418364291cac61c746049b0cd7bc219","tests/basics.rs":"21fea3f4ade43c0cb1699a3e2559ab5b3fdf7120464f6bd698bea24b994c6e88","tests/ref.rs":"dffad50e3cf2b3b8daae08c16c86d88841fb1a7b349d580891692ad23d7ec1e0"},"package":"4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d"} \ No newline at end of file diff --git a/vendor/derive_setters/Cargo.toml b/vendor/derive_setters/Cargo.toml new file mode 100644 index 000000000..a75179e10 --- /dev/null +++ b/vendor/derive_setters/Cargo.toml @@ -0,0 +1,38 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2018" +name = "derive_setters" +version = "0.1.6" +authors = ["Lymia Aluysia "] +description = "Rust macro to automatically generates setter methods for a struct's fields." +readme = "README.md" +license = "MIT/Apache-2.0" +repository = "https://github.com/Lymia/derive_setters" + +[lib] +proc-macro = true + +[dependencies.darling] +version = "0.20" + +[dependencies.proc-macro2] +version = "1" + +[dependencies.quote] +version = "1" + +[dependencies.syn] +version = "2" + +[features] +nightly = ["proc-macro2/nightly"] diff --git a/vendor/derive_setters/README.md b/vendor/derive_setters/README.md new file mode 100644 index 000000000..afd92cdcf --- /dev/null +++ b/vendor/derive_setters/README.md @@ -0,0 +1,79 @@ +# derive_setters + +[![Build Status](https://api.travis-ci.com/Lymia/derive_setters.svg?branch=master)](https://travis-ci.com/Lymia/derive_setters) +[![Latest Version](https://img.shields.io/crates/v/derive_setters.svg)](https://crates.io/crates/derive_setters) +![Requires rustc 1.56+](https://img.shields.io/badge/rustc-1.56+-red.svg) + +Rust macro to automatically generates setter methods for a struct's fields. This can be used to add setters to a plain +data struct, or to help in implementing builders. + +For a related library that creates separate builder types, see +[`rust-derive-builder`](https://github.com/colin-kiegel/rust-derive-builder). + +# Basic usage example + +```rust +use derive_setters::*; + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +struct BasicStruct { + #[setters(rename = "test")] + a: u32, + b: u32, + c: u32, +} + +assert_eq!( + BasicStruct::default().test(30).b(10).c(20), + BasicStruct { a: 30, b: 10, c: 20 }, +); +``` + +# Additional options + +The following options can be set on the entire struct. + +* `#[setters(generate = false)]` causes setter methods to not be generated by default. +* `#[setters(generate_private = false)]` causes setter methods to not be generated by default for private fields. +* `#[setters(generate_public = false)]` causes setter methods to not be generated by default for public fields. +* `#[setters(no_std)]` causes the generated code to use `core` instead of `std`. +* `#[setters(prefix = "with_")]` causes the setter method on all fields to be prefixed with the given string. +* `#[setters(generate_delegates(ty = "OtherTy", field = "some_field"))]` causes all setter methods on this struct to + be duplicated on the target struct, instead modifying `self.some_field` instead of `self`. +* `#[setters(generate_delegates(ty = "OtherTy", method = "get_field"))]` does the same thing as above, except calling + `get_field` with no arguments instead of directly accessing a field. + +The following options can be set on a fields. + +* `#[setters(generate)]` causes a setter method to be generated, overriding struct-level settings. +* `#[setters(skip)]` causes no setter method to be generated. +* `#[setters(rename = "setter_name")]` causes the setter method to have a different name from the field. + This overwrites `add_prefix`. + +The following options can be set on either the entire struct, or on an individual field. You +can disable the features for a particular field with `#[setters(option = false)]` + +* `#[setters(into)]` causes the setter method to accept any type that can be converted into the field's type + via `Into`. +* `#[setters(strip_option)]` causes the setter method to accept `T` instead of `Option`. If applied to a field + that isn't wrapped in an `Option`, it does nothing. +* `#[setters(bool)]` causes the setter method to take no arguments, and set the field to `true`. +* `#[setters(borrow_self)]` causes the generated setter method to borrow `&mut self` instead of taking `self`. This + is better for code styles that require mutable setters rather than immutable setters. + +# License + +This project is licensed under either of + + * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in enumset by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/vendor/derive_setters/src/lib.rs b/vendor/derive_setters/src/lib.rs new file mode 100644 index 000000000..25c253d82 --- /dev/null +++ b/vendor/derive_setters/src/lib.rs @@ -0,0 +1,369 @@ +#![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))] + +extern crate proc_macro; + +use darling::*; +use darling::util::Flag; +use proc_macro::TokenStream; +use proc_macro2::{Span, TokenStream as SynTokenStream}; +use std::result::Result; +use syn::*; +use syn::spanned::Spanned; +use quote::*; + +#[cfg(feature = "nightly")] +fn error(span: Span, data: &str) -> SynTokenStream { + span.unstable().error(data).emit(); + SynTokenStream::new() +} + +#[cfg(not(feature = "nightly"))] +fn error(_: Span, data: &str) -> SynTokenStream { + quote! { compile_error!(#data); } +} + +#[derive(Debug, Clone, FromMeta)] +struct ExternalDelegate { + /// The type to generate a delegate for. + ty: Path, + /// The field to delegate the methods to. + #[darling(default)] + field: Option, + /// The method to delegate the methods to. + #[darling(default)] + method: Option, +} + +#[derive(Debug, Clone, FromDeriveInput)] +#[darling(attributes(setters), supports(struct_named))] +struct ContainerAttrs { + ident: Ident, + generics: Generics, + + /// Use the core library rather than the std library. + #[darling(default)] + no_std: Flag, + + /// Whether to accept any field that converts via `Into` by default. + #[darling(default)] + into: bool, + + /// Whether to strip `Option` into `T` in the parameters for the setter method by default. + #[darling(default)] + strip_option: bool, + + /// Whether to borrow or take ownership of `self` in the setter method by default. + #[darling(default)] + borrow_self: bool, + + /// Whether to generate a method that sets a boolean by default. + #[darling(default)] + bool: bool, + + /// Whether to generate setters for this struct's fields by default. If set to false, + /// `generate_public` and `generate_private` are ignored. + #[darling(default)] + generate: Option, + + /// Whether to generate setters for this struct's public fields by default. + #[darling(default)] + generate_public: Option, + + /// Whether to generate setters for this struct's private fields by default. + #[darling(default)] + generate_private: Option, + + /// A prefix for the generated setter methods. + #[darling(default)] + prefix: Option, + + /// Other types to generate delegates to this type for. Note that this does not support + /// generics. + #[darling(multiple)] + generate_delegates: Vec, +} + +#[derive(Debug, Clone, FromField)] +#[darling(attributes(setters), forward_attrs(doc))] +struct FieldAttrs { + attrs: Vec, + + /// The name of the generated setter method. + #[darling(default)] + rename: Option, + + /// Whether to accept any field that converts via `Into` to this field's type. + #[darling(default)] + into: Option, + + /// Whether to strip `Option` into `T` in the parameters for the setter method. + #[darling(default)] + strip_option: Option, + + /// Whether to borrow or take ownership of `self` for the setter method. + #[darling(default)] + borrow_self: Option, + + /// Whether to generate a method that sets a boolean. + #[darling(default)] + bool: Option, + + /// Whether to generate a setter for this field regardless of global settings. + #[darling(default)] + generate: bool, + + /// Whether to skip this field regardless of global settings. Overwrites `generate`. + #[darling(default)] + skip: bool, +} + +struct ContainerDef { + name: Ident, + ty: Type, + std: Ident, + generics: Generics, + + prefix: String, + uses_into: bool, + strip_option: bool, + borrow_self: bool, + bool: bool, + generate_public: bool, + generate_private: bool, + + generate_delegates: Vec, +} + +struct FieldDef { + field_name: Ident, + field_ty: Type, + field_doc: SynTokenStream, + setter_name: Ident, + uses_into: bool, + strip_option: bool, + borrow_self: bool, + bool: bool, +} + +fn init_container_def(input: &DeriveInput) -> Result { + let darling_attrs: ContainerAttrs = match FromDeriveInput::from_derive_input(input) { + Ok(v) => v, + Err(e) => return Err(e.write_errors()), + }; + + let ident = &darling_attrs.ident; + let (_, generics_ty, _) = darling_attrs.generics.split_for_impl(); + let ty = quote! { #ident #generics_ty }; + + let generate = darling_attrs.generate.unwrap_or(true); + Ok(ContainerDef { + name: darling_attrs.ident, + ty: parse2(ty).expect("Internal error: failed to parse internally generated type."), + std: if darling_attrs.no_std.is_present() { + Ident::new("core", Span::call_site()) + } else { + Ident::new("std", Span::call_site()) + }, + borrow_self: darling_attrs.borrow_self, + generics: darling_attrs.generics, + prefix: darling_attrs.prefix.unwrap_or(String::new()), + uses_into: darling_attrs.into, + strip_option: darling_attrs.strip_option, + bool: darling_attrs.bool, + generate_public: generate && darling_attrs.generate_public.unwrap_or(true), + generate_private: generate && darling_attrs.generate_private.unwrap_or(true), + generate_delegates: darling_attrs.generate_delegates, + }) +} + +fn init_field_def( + container: &ContainerDef, field: &Field, +) -> Result, SynTokenStream> { + // Decode the various attribute options. + let darling_attrs: FieldAttrs = match FromField::from_field(field) { + Ok(v) => v, + Err(e) => return Err(e.write_errors()), + }; + + // Check whether this field should generate a setter. + if darling_attrs.skip { return Ok(None) } + let generates = match field.vis { + Visibility::Public(_) => container.generate_public, + _ => container.generate_private, + }; + if !(darling_attrs.generate || generates) { return Ok(None) } + + // Returns a definition for this field. + let ident = match &field.ident { + Some(i) => i.clone(), + None => panic!("Internal error: init_field_def on wrong item."), + }; + Ok(Some(FieldDef { + field_name: ident.clone(), + field_ty: field.ty.clone(), + field_doc: if let Visibility::Public(_) = field.vis { + let doc_str = + format!("Sets the [`{}`](#structfield.{}) field of this struct.", ident, ident); + quote! { #[doc = #doc_str] } + } else { + let attrs = darling_attrs.attrs; + quote! { #( #attrs )* } + }, + setter_name: darling_attrs.rename.unwrap_or_else(|| + Ident::new(&format!("{}{}", container.prefix, ident), ident.span()) + ), + uses_into: darling_attrs.into.unwrap_or(container.uses_into), + strip_option: darling_attrs.strip_option.unwrap_or(container.strip_option), + borrow_self: darling_attrs.borrow_self.unwrap_or(container.borrow_self), + bool: darling_attrs.bool.unwrap_or(container.bool), + })) +} + + +fn generate_setter_method( + container: &ContainerDef, def: FieldDef, delegate_toks: &Option, +) -> Result { + let FieldDef { + field_name, mut field_ty, field_doc, setter_name, .. + } = def; + let std = &container.std; + + // Strips `Option` into `T` if the `strip_option` property is set. + let mut stripped_option = false; + if def.strip_option { + if let Type::Path(path) = &field_ty { + let segment = path.path.segments.last().unwrap(); + if segment.ident.to_string() == "Option" { + if let PathArguments::AngleBracketed(path) = &segment.arguments { + if let GenericArgument::Type(tp) = path.args.first().unwrap() { + field_ty = tp.clone(); + stripped_option = true; + } + } + } + } + } + + // The type the setter accepts. + let value_ty = if def.uses_into { + quote! { impl ::#std::convert::Into<#field_ty> } + } else { + quote! { #field_ty } + }; + + // The expression actually stored into the field. + let mut expr = quote! { value }; + if def.uses_into { expr = quote! { #expr.into() }; } + if def.bool { expr = quote! { true }; } + if stripped_option { expr = quote! { Some(#expr) }; } + + // Handle the parameters when bool is enabled. + let params = if def.bool { + SynTokenStream::new() + } else { + quote! { value: #value_ty } + }; + + // Generates the setter method itself. + let container_name = &container.name; + if let Some(delegate) = delegate_toks { + let _self = if def.borrow_self { + quote! { &mut self } + } else { + quote! { mut self } + }; + + let return_self = if def.borrow_self { + quote! { &mut Self } + } else { + quote! { Self } + }; + + Ok(quote! { + #field_doc + pub fn #setter_name (#_self, #params) -> #return_self { + self.#delegate.#field_name = #expr; + self + } + }) + } else { + if def.borrow_self { + Ok(quote! { + #field_doc + pub fn #setter_name (&mut self, #params) -> &mut Self { + self.#field_name = #expr; + self + } + }) + } else { + Ok(quote! { + #field_doc + pub fn #setter_name (self, #params) -> Self { + #container_name { #field_name: #expr, ..self } + } + }) + } + } +} + +fn generate_setters_for( + input: &DeriveInput, data: &DataStruct, generics: &Generics, + ty: SynTokenStream, delegate_toks: Option, +) -> Result { + let container_def = init_container_def(&input)?; + let mut toks = SynTokenStream::new(); + for field in &data.fields { + if let Some(field_def) = init_field_def(&container_def, field)? { + let method = generate_setter_method(&container_def, field_def, &delegate_toks)?; + toks.extend(method); + } + } + + let (generics_bound, _, generics_where) = generics.split_for_impl(); + Ok(quote! { + impl #generics_bound #ty #generics_where { + #toks + } + }) + +} + +fn generate_setters(input: &DeriveInput, data: &DataStruct) -> Result { + let container_def = init_container_def(&input)?; + let mut toks = SynTokenStream::new(); + let container_ty = &container_def.ty; + toks.extend(generate_setters_for( + input, data, &container_def.generics, quote! { #container_ty }, None, + )); + for delegate in container_def.generate_delegates { + let delegate_ty = delegate.ty; + toks.extend(generate_setters_for( + input, data, &Generics::default(), quote! { #delegate_ty }, + if delegate.field.is_some() && delegate.method.is_some() { + return Err(error(input.span(), + "Cannot set both `method` and `field` on a delegate.").into()); + } else if let Some(field) = &delegate.field { + Some(quote! { #field }) + } else if let Some(method) = &delegate.method { + Some(quote! { #method() }) + } else { + return Err(error(input.span(), + "Must set either `method` or `field` on a delegate.").into()); + } + )); + } + Ok(toks.into()) +} + +#[proc_macro_derive(Setters, attributes(setters))] +pub fn derive_setters(input: TokenStream) -> TokenStream { + let input: DeriveInput = parse_macro_input!(input); + if let Data::Struct(data) = &input.data { + match generate_setters(&input, data) { + Ok(toks) => toks, + Err(toks) => toks, + } + } else { + error(input.span(), "`#[derive(Setters)] may only be used on structs.").into() + } +} diff --git a/vendor/derive_setters/tests/basics.rs b/vendor/derive_setters/tests/basics.rs new file mode 100644 index 000000000..0195c7d3c --- /dev/null +++ b/vendor/derive_setters/tests/basics.rs @@ -0,0 +1,156 @@ +use derive_setters::*; + +use std::borrow::Cow; + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(generate_delegates(ty = "BasicDelegateField", field = "x"))] +#[setters(generate_delegates(ty = "BasicDelegateMethod", method = "get_x"))] +struct BasicStruct { + #[setters(rename = "test")] + a: u32, + b: u32, + c: u32, +} + +#[derive(Default, Debug, PartialEq, Eq)] +struct BasicDelegateField { + x: BasicStruct, +} + +#[derive(Default, Debug, PartialEq, Eq)] +struct BasicDelegateMethod { + x: Option, +} +impl BasicDelegateMethod { + fn get_x(&mut self) -> &mut BasicStruct { + if self.x.is_none() { + self.x = Some(BasicStruct::default()); + } + self.x.as_mut().unwrap() + } +} + +#[test] +fn basic_struct() { + assert_eq!( + BasicStruct::default().test(30).b(10).c(20), + BasicStruct { a: 30, b: 10, c: 20 }, + ); + assert_eq!( + BasicStruct::default().b(15).test(10), + BasicStruct { a: 10, b: 15, ..Default::default() }, + ); +} + +#[test] +fn delegated_structs() { + assert_eq!( + BasicDelegateField::default().b(15).test(10), + BasicDelegateField { x: BasicStruct { a: 10, b: 15, ..Default::default() } }, + ); + assert_eq!( + BasicDelegateMethod::default().b(15).test(10), + BasicDelegateMethod { x: Some(BasicStruct { a: 10, b: 15, ..Default::default() }) }, + ); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +struct GenericStruct<'a, T> { + a: Option<&'a T>, + b: Option<&'a T>, + c: T, +} + +#[test] +fn generic_struct() { + assert_eq!( + GenericStruct::default().a(Some(&30)).b(Some(&10)).c(20), + GenericStruct { a: Some(&30), b: Some(&10), c: 20 }, + ); + assert_eq!( + GenericStruct::default().b(Some(&15)).a(Some(&10)), + GenericStruct { a: Some(&10), b: Some(&15), ..Default::default() }, + ); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(strip_option)] +struct StripOptionStruct { + a: Option, + b: core::option::Option, + c: std::option::Option, + d: u32, +} + +#[test] +fn strip_option_struct() { + assert_eq!( + StripOptionStruct::default().a(3).b(42).c(43).d(7), + StripOptionStruct { a: Some(3), b: Some(42), c: Some(43), d: 7 }, + ); + assert_eq!( + StripOptionStruct::default().b(6), + StripOptionStruct { a: None, b: Some(6), c: None, d: 0 }, + ); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(into, strip_option)] +struct IntoStruct<'a> { + a: Cow<'a, str>, + b: Option>, +} + +#[test] +fn into_struct() { + let testb = "testb".to_string(); + assert_eq!( + IntoStruct::default().a("testa").b(&testb), + IntoStruct { a: "testa".into(), b: Some("testb".into()) }, + ); + assert_eq!( + IntoStruct::default().a("testa").b(testb), + IntoStruct { a: "testa".into(), b: Some("testb".into()) }, + ); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(prefix = "with_")] +struct WithStruct { + #[setters(rename = "test")] + a: u32, + b: u32, + c: u32, +} + +#[test] +fn with_struct() { + assert_eq!( + WithStruct::default().test(30).with_b(10).with_c(20), + WithStruct { a: 30, b: 10, c: 20 }, + ); + assert_eq!( + WithStruct::default().with_b(15).test(10), + WithStruct { a: 10, b: 15, ..Default::default() }, + ); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(bool)] +struct BoolStruct { + a: bool, + b: bool, + c: bool, +} + +#[test] +fn bool_struct() { + assert_eq!( + BoolStruct::default().a().c(), + BoolStruct { a: true, b: false, c: true }, + ); + assert_eq!( + BoolStruct::default().b().a(), + BoolStruct { a: true, b: true, c: false }, + ); +} diff --git a/vendor/derive_setters/tests/ref.rs b/vendor/derive_setters/tests/ref.rs new file mode 100644 index 000000000..b8efc01a4 --- /dev/null +++ b/vendor/derive_setters/tests/ref.rs @@ -0,0 +1,90 @@ +use derive_setters::*; + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(borrow_self)] +struct BasicRefStruct { + #[setters(rename = "test")] + a: u32, + b: u32, + #[setters(borrow_self = "false")] + c: u32, + #[setters(borrow_self = false)] + d: u32, +} + +#[test] +fn basic_ref_struct() { + let mut a = BasicRefStruct::default().c(34).d(4); + a.test(1); + a.b(3); + + assert_eq!(a.a, 1); + assert_eq!(a.b, 3); + assert_eq!(a.c, 34); + assert_eq!(a.d, 4); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +struct FieldRefStruct { + a: u32, + #[setters(borrow_self)] + b: u32, +} + +#[test] +fn field_ref_struct() { + let mut a = FieldRefStruct::default().a(10); + a.b(20); + + assert_eq!(a.a, 10); + assert_eq!(a.b, 20); +} + +#[derive(Default, Setters, Debug, PartialEq, Eq)] +#[setters(borrow_self)] +#[setters(generate_delegates(ty = "BasicRefDelegateField", field = "x"))] +#[setters(generate_delegates(ty = "BasicRefDelegateMethod", method = "get_x"))] +struct InnerRefDelegateStruct { + #[setters(rename = "test")] + a: u32, + b: u32, + c: u32, +} + +#[derive(Default, Debug, PartialEq, Eq)] +struct BasicRefDelegateField { + x: InnerRefDelegateStruct, +} + +#[derive(Default, Debug, PartialEq, Eq)] +struct BasicRefDelegateMethod { + x: Option, +} +impl BasicRefDelegateMethod { + fn get_x(&mut self) -> &mut InnerRefDelegateStruct { + if self.x.is_none() { + self.x = Some(InnerRefDelegateStruct::default()); + } + self.x.as_mut().unwrap() + } +} + +#[test] +fn basic_ref_delegate_field() { + let mut a = BasicRefDelegateField::default(); + a.test(1); + a.b(3); + a.c(34); + + assert_eq!(a.x, InnerRefDelegateStruct{ a: 1, b: 3, c: 34 }); +} + +#[test] +fn basic_ref_delegate_method() { + let mut a = BasicRefDelegateMethod::default(); + a.test(1); + a.b(3); + a.c(34); + + assert_eq!(a.x, Some(InnerRefDelegateStruct{ a: 1, b: 3, c: 34 })); +} -- cgit v1.2.3