From 5363f350887b1e5b5dd21a86f88c8af9d7fea6da Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:25 +0200 Subject: Merging upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/icu_provider_macros/.cargo-checksum.json | 1 + vendor/icu_provider_macros/Cargo.toml | 47 +++++ vendor/icu_provider_macros/LICENSE | 51 +++++ vendor/icu_provider_macros/README.md | 9 + vendor/icu_provider_macros/src/lib.rs | 268 ++++++++++++++++++++++++ vendor/icu_provider_macros/src/tests.rs | 210 +++++++++++++++++++ 6 files changed, 586 insertions(+) create mode 100644 vendor/icu_provider_macros/.cargo-checksum.json create mode 100644 vendor/icu_provider_macros/Cargo.toml create mode 100644 vendor/icu_provider_macros/LICENSE create mode 100644 vendor/icu_provider_macros/README.md create mode 100644 vendor/icu_provider_macros/src/lib.rs create mode 100644 vendor/icu_provider_macros/src/tests.rs (limited to 'vendor/icu_provider_macros') diff --git a/vendor/icu_provider_macros/.cargo-checksum.json b/vendor/icu_provider_macros/.cargo-checksum.json new file mode 100644 index 000000000..21caa79bb --- /dev/null +++ b/vendor/icu_provider_macros/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"5c2656c9d6a8256494d0d58648ba09110cb602fa81b59580e758695704299664","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"f9f95075851c9c3b7d0559c25794ebcad5dee957c7fb27c343418a3324f15b8a","src/lib.rs":"e3f9092950ee1db12dbbd5b3fea39aead909896ee317f5b38a6442c209e37d03","src/tests.rs":"729a551b69f368100b142a3260573307b653931228cdc803eeffbb81910134f7"},"package":"38cf6f5b65cf81f0b4298da647101acbfe6ae0e25263f92bd7a22597e9d6d606"} \ No newline at end of file diff --git a/vendor/icu_provider_macros/Cargo.toml b/vendor/icu_provider_macros/Cargo.toml new file mode 100644 index 000000000..1f2350f36 --- /dev/null +++ b/vendor/icu_provider_macros/Cargo.toml @@ -0,0 +1,47 @@ +# 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 = "icu_provider_macros" +version = "1.0.0" +authors = ["The ICU4X Project Developers"] +include = [ + "src/**/*", + "examples/**/*", + "benches/**/*", + "tests/**/*", + "Cargo.toml", + "LICENSE", + "README.md", +] +description = "Proc macros for ICU data providers" +readme = "README.md" +categories = ["internationalization"] +license = "Unicode-DFS-2016" +repository = "https://github.com/unicode-org/icu4x" +resolver = "2" + +[lib] +path = "src/lib.rs" +proc-macro = true + +[dependencies.proc-macro2] +version = "1.0.27" + +[dependencies.quote] +version = "1.0.9" + +[dependencies.syn] +version = "1.0.73" +features = ["full"] + +[dev-dependencies] diff --git a/vendor/icu_provider_macros/LICENSE b/vendor/icu_provider_macros/LICENSE new file mode 100644 index 000000000..9858d01ab --- /dev/null +++ b/vendor/icu_provider_macros/LICENSE @@ -0,0 +1,51 @@ +UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE + +See Terms of Use +for definitions of Unicode Inc.’s Data Files and Software. + +NOTICE TO USER: Carefully read the following legal agreement. +BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S +DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), +YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. +IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE +THE DATA FILES OR SOFTWARE. + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2022 Unicode, Inc. All rights reserved. +Distributed under the Terms of Use in https://www.unicode.org/copyright.html. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Unicode data files and any associated documentation +(the "Data Files") or Unicode software and any associated documentation +(the "Software") to deal in the Data Files or Software +without restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, and/or sell copies of +the Data Files or Software, and to permit persons to whom the Data Files +or Software are furnished to do so, provided that either +(a) this copyright and permission notice appear with all copies +of the Data Files or Software, or +(b) this copyright and permission notice appear in associated +Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT OF THIRD PARTY RIGHTS. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS +NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL +DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THE DATA FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, +use or other dealings in these Data Files or Software without prior +written authorization of the copyright holder. + +— + +Portions of ICU4X may have been adapted from ICU4C and/or ICU4J. +ICU 1.8.1 to ICU 57.1 © 1995-2016 International Business Machines Corporation and others. diff --git a/vendor/icu_provider_macros/README.md b/vendor/icu_provider_macros/README.md new file mode 100644 index 000000000..c9ea9d21c --- /dev/null +++ b/vendor/icu_provider_macros/README.md @@ -0,0 +1,9 @@ +# icu_provider_macros [![crates.io](https://img.shields.io/crates/v/icu_provider_macros)](https://crates.io/crates/icu_provider_macros) + +Proc macros for the ICU4X data provider. + +These macros are re-exported from `icu_provider`. + +## More Information + +For more information on development, authorship, contributing etc. please visit [`ICU4X home page`](https://github.com/unicode-org/icu4x). diff --git a/vendor/icu_provider_macros/src/lib.rs b/vendor/icu_provider_macros/src/lib.rs new file mode 100644 index 000000000..e43cebfce --- /dev/null +++ b/vendor/icu_provider_macros/src/lib.rs @@ -0,0 +1,268 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +// https://github.com/unicode-org/icu4x/blob/main/docs/process/boilerplate.md#library-annotations +#![cfg_attr( + not(test), + deny( + clippy::indexing_slicing, + clippy::unwrap_used, + clippy::expect_used, + // Panics are OK in proc macros + // clippy::panic, + clippy::exhaustive_structs, + clippy::exhaustive_enums, + missing_debug_implementations, + ) +)] +#![warn(missing_docs)] + +//! Proc macros for the ICU4X data provider. +//! +//! These macros are re-exported from `icu_provider`. + +extern crate proc_macro; +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::parse_macro_input; +use syn::spanned::Spanned; +use syn::AttributeArgs; +use syn::DeriveInput; +use syn::Lit; +use syn::Meta; +use syn::NestedMeta; + +#[cfg(test)] +mod tests; + +#[proc_macro_attribute] +/// The `#[data_struct]` attribute should be applied to all types intended +/// for use in a `DataStruct`. +/// +/// It does the following things: +/// +/// - `Apply #[derive(Yokeable, ZeroFrom)]`. The `ZeroFrom` derive can +/// be customized with `#[zerofrom(clone)]` on non-ZeroFrom fields. +/// +/// In addition, the attribute can be used to implement `DataMarker` and/or `KeyedDataMarker` +/// by adding symbols with optional key strings: +/// +/// ``` +/// use icu_provider::prelude::*; +/// use std::borrow::Cow; +/// +/// #[icu_provider::data_struct( +/// FooV1Marker, +/// BarV1Marker = "demo/bar@1", +/// marker( +/// BazV1Marker, +/// "demo/baz@1", +/// fallback_by = "region", +/// extension_key = "ca" +/// ) +/// )] +/// pub struct FooV1<'data> { +/// message: Cow<'data, str>, +/// }; +/// +/// // Note: FooV1Marker implements `DataMarker` but not `KeyedDataMarker`. +/// // The other two implement `KeyedDataMarker`. +/// +/// assert_eq!(&*BarV1Marker::KEY.path(), "demo/bar@1"); +/// assert_eq!( +/// BarV1Marker::KEY.metadata().fallback_priority, +/// icu_provider::FallbackPriority::Language +/// ); +/// assert_eq!(BarV1Marker::KEY.metadata().extension_key, None); +/// +/// assert_eq!(&*BazV1Marker::KEY.path(), "demo/baz@1"); +/// assert_eq!( +/// BazV1Marker::KEY.metadata().fallback_priority, +/// icu_provider::FallbackPriority::Region +/// ); +/// assert_eq!( +/// BazV1Marker::KEY.metadata().extension_key, +/// Some(icu::locid::extensions_unicode_key!("ca")) +/// ); +/// ``` +/// +/// If the `#[databake(path = ...)]` attribute is present on the data struct, this will also +/// implement it on the markers. +pub fn data_struct(attr: TokenStream, item: TokenStream) -> TokenStream { + TokenStream::from(data_struct_impl( + parse_macro_input!(attr as AttributeArgs), + parse_macro_input!(item as DeriveInput), + )) +} + +fn data_struct_impl(attr: AttributeArgs, input: DeriveInput) -> TokenStream2 { + if input.generics.type_params().count() > 0 { + return syn::Error::new( + input.generics.span(), + "#[data_struct] does not support type parameters", + ) + .to_compile_error(); + } + let lifetimes = input.generics.lifetimes().collect::>(); + + let name = &input.ident; + + let name_with_lt = if lifetimes.get(0).is_some() { + quote!(#name<'static>) + } else { + quote!(#name) + }; + + if lifetimes.len() > 1 { + return syn::Error::new( + input.generics.span(), + "#[data_struct] does not support more than one lifetime parameter", + ) + .to_compile_error(); + } + + let bake_derive = input + .attrs + .iter() + .find(|a| a.path.is_ident("databake")) + .map(|a| { + quote! { + #[derive(Default, databake::Bake)] + #a + } + }) + .unwrap_or_else(|| quote! {}); + + let mut result = TokenStream2::new(); + + for single_attr in attr.into_iter() { + let mut marker_name: Option = None; + let mut key_lit: Option = None; + let mut fallback_by: Option = None; + let mut extension_key: Option = None; + let mut fallback_supplement: Option = None; + + match single_attr { + NestedMeta::Meta(Meta::List(meta_list)) => { + match meta_list.path.get_ident() { + Some(ident) if ident.to_string().as_str() == "marker" => (), + _ => panic!("Meta list must be `marker(...)`"), + } + for inner_meta in meta_list.nested.into_iter() { + match inner_meta { + NestedMeta::Meta(Meta::Path(path)) => { + marker_name = Some(path); + } + NestedMeta::Lit(Lit::Str(lit_str)) => { + key_lit = Some(lit_str); + } + NestedMeta::Meta(Meta::NameValue(name_value)) => { + let lit_str = match name_value.lit { + Lit::Str(lit_str) => lit_str, + _ => panic!("Values in marker() must be strings"), + }; + let name_ident_str = match name_value.path.get_ident() { + Some(ident) => ident.to_string(), + None => panic!("Names in marker() must be identifiers"), + }; + match name_ident_str.as_str() { + "fallback_by" => fallback_by = Some(lit_str), + "extension_key" => extension_key = Some(lit_str), + "fallback_supplement" => fallback_supplement = Some(lit_str), + _ => panic!("Invalid argument name in marker()"), + } + } + _ => panic!("Invalid argument in marker()"), + } + } + } + NestedMeta::Meta(Meta::NameValue(name_value)) => { + marker_name = Some(name_value.path); + match name_value.lit { + syn::Lit::Str(lit_str) => key_lit = Some(lit_str), + _ => panic!("Key must be a string"), + }; + } + NestedMeta::Meta(Meta::Path(path)) => { + marker_name = Some(path); + } + _ => { + panic!("Invalid attribute to #[data_struct]") + } + } + + let marker_name = match marker_name { + Some(path) => path, + None => panic!("#[data_struct] arguments must include a marker name"), + }; + + let docs = if let Some(key_lit) = &key_lit { + let fallback_by_docs_str = match &fallback_by { + Some(fallback_by) => fallback_by.value(), + None => "language (default)".to_string(), + }; + let extension_key_docs_str = match &extension_key { + Some(extension_key) => extension_key.value(), + None => "none (default)".to_string(), + }; + format!("Marker type for [`{}`]: \"{}\"\n\n- Fallback priority: {}\n- Extension keyword: {}", name, key_lit.value(), fallback_by_docs_str, extension_key_docs_str) + } else { + format!("Marker type for [`{}`]", name) + }; + + result.extend(quote!( + #[doc = #docs] + #bake_derive + pub struct #marker_name; + impl icu_provider::DataMarker for #marker_name { + type Yokeable = #name_with_lt; + } + )); + + if let Some(key_lit) = &key_lit { + let key_str = key_lit.value(); + let fallback_by_expr = if let Some(fallback_by_lit) = fallback_by { + match fallback_by_lit.value().as_str() { + "region" => quote! {icu_provider::FallbackPriority::Region}, + "collation" => quote! {icu_provider::FallbackPriority::Collation}, + "language" => quote! {icu_provider::FallbackPriority::Language}, + _ => panic!("Invalid value for fallback_by"), + } + } else { + quote! {icu_provider::FallbackPriority::const_default()} + }; + let extension_key_expr = if let Some(extension_key_lit) = extension_key { + quote! {Some(icu_provider::_internal::extensions_unicode_key!(#extension_key_lit))} + } else { + quote! {None} + }; + let fallback_supplement_expr = + if let Some(fallback_supplement_lit) = fallback_supplement { + match fallback_supplement_lit.value().as_str() { + "collation" => quote! {Some(icu_provider::FallbackSupplement::Collation)}, + _ => panic!("Invalid value for fallback_supplement"), + } + } else { + quote! {None} + }; + result.extend(quote!( + impl icu_provider::KeyedDataMarker for #marker_name { + const KEY: icu_provider::DataKey = icu_provider::data_key!(#key_str, icu_provider::DataKeyMetadata::construct_internal( + #fallback_by_expr, + #extension_key_expr, + #fallback_supplement_expr + )); + } + )); + } + } + + result.extend(quote!( + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + #input + )); + + result +} diff --git a/vendor/icu_provider_macros/src/tests.rs b/vendor/icu_provider_macros/src/tests.rs new file mode 100644 index 000000000..51411852b --- /dev/null +++ b/vendor/icu_provider_macros/src/tests.rs @@ -0,0 +1,210 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +use crate::data_struct_impl; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{DeriveInput, NestedMeta}; + +fn check(attr: Vec, item: TokenStream2, expected: TokenStream2) { + let actual = data_struct_impl( + attr.into_iter() + .map(syn::parse2) + .collect::>>() + .unwrap(), + syn::parse2::(item).unwrap(), + ); + assert_eq!(expected.to_string(), actual.to_string()); +} + +#[test] +fn test_basic() { + // #[data_struct] + check( + vec![], + quote!( + pub struct FooV1; + ), + quote!( + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + pub struct FooV1; + ), + ); +} + +#[test] +fn test_data_marker() { + // #[data_struct(FooV1Marker)] + check( + vec![quote!(FooV1Marker)], + quote!( + pub struct FooV1; + ), + quote!( + #[doc = "Marker type for [`FooV1`]"] + pub struct FooV1Marker; + impl icu_provider::DataMarker for FooV1Marker { + type Yokeable = FooV1; + } + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + pub struct FooV1; + ), + ); +} + +#[test] +fn test_keyed_data_marker() { + // #[data_struct(BarV1Marker = "demo/bar@1")] + check( + vec![quote!(BarV1Marker = "demo/bar@1")], + quote!( + pub struct FooV1; + ), + quote!( + #[doc = "Marker type for [`FooV1`]: \"demo/bar@1\"\n\n- Fallback priority: language (default)\n- Extension keyword: none (default)"] + pub struct BarV1Marker; + impl icu_provider::DataMarker for BarV1Marker { + type Yokeable = FooV1; + } + impl icu_provider::KeyedDataMarker for BarV1Marker { + const KEY: icu_provider::DataKey = icu_provider::data_key!( + "demo/bar@1", + icu_provider::DataKeyMetadata::construct_internal( + icu_provider::FallbackPriority::const_default(), + None, + None + )); + } + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + pub struct FooV1; + ), + ); +} + +#[test] +fn test_multi_named_keyed_data_marker() { + // #[data_struct(FooV1Marker, BarV1Marker = "demo/bar@1", BazV1Marker = "demo/baz@1")] + check( + vec![ + quote!(FooV1Marker), + quote!(BarV1Marker = "demo/bar@1"), + quote!(BazV1Marker = "demo/baz@1"), + ], + quote!( + pub struct FooV1<'data>; + ), + quote!( + #[doc = "Marker type for [`FooV1`]"] + pub struct FooV1Marker; + impl icu_provider::DataMarker for FooV1Marker { + type Yokeable = FooV1<'static>; + } + #[doc = "Marker type for [`FooV1`]: \"demo/bar@1\"\n\n- Fallback priority: language (default)\n- Extension keyword: none (default)"] + pub struct BarV1Marker; + impl icu_provider::DataMarker for BarV1Marker { + type Yokeable = FooV1<'static>; + } + impl icu_provider::KeyedDataMarker for BarV1Marker { + const KEY: icu_provider::DataKey = icu_provider::data_key!( + "demo/bar@1", + icu_provider::DataKeyMetadata::construct_internal( + icu_provider::FallbackPriority::const_default(), + None, + None + )); + } + #[doc = "Marker type for [`FooV1`]: \"demo/baz@1\"\n\n- Fallback priority: language (default)\n- Extension keyword: none (default)"] + pub struct BazV1Marker; + impl icu_provider::DataMarker for BazV1Marker { + type Yokeable = FooV1<'static>; + } + impl icu_provider::KeyedDataMarker for BazV1Marker { + const KEY: icu_provider::DataKey = icu_provider::data_key!( + "demo/baz@1", + icu_provider::DataKeyMetadata::construct_internal( + icu_provider::FallbackPriority::const_default(), + None, + None + )); + } + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + pub struct FooV1<'data>; + ), + ); +} + +#[test] +fn test_databake() { + check( + vec![quote!(BarV1Marker = "demo/bar@1")], + quote!( + #[databake(path = test::path)] + pub struct FooV1; + ), + quote!( + #[doc = "Marker type for [`FooV1`]: \"demo/bar@1\"\n\n- Fallback priority: language (default)\n- Extension keyword: none (default)"] + #[derive(Default, databake::Bake)] + #[databake(path = test::path)] + pub struct BarV1Marker; + impl icu_provider::DataMarker for BarV1Marker { + type Yokeable = FooV1; + } + impl icu_provider::KeyedDataMarker for BarV1Marker { + const KEY: icu_provider::DataKey = icu_provider::data_key!( + "demo/bar@1", + icu_provider::DataKeyMetadata::construct_internal( + icu_provider::FallbackPriority::const_default(), + None, + None + )); + } + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + #[databake(path = test::path)] + pub struct FooV1; + ), + ); +} + +#[test] +fn test_attributes() { + // #[data_struct(FooV1Marker, marker(BarV1Marker, "demo/bar@1", fallback_by = "region", extension_kw = "ca"))] + check( + vec![ + quote!(FooV1Marker), + quote!(marker( + BarV1Marker, + "demo/bar@1", + fallback_by = "region", + extension_key = "ca", + fallback_supplement = "collation" + )), + ], + quote!( + pub struct FooV1<'data>; + ), + quote!( + #[doc = "Marker type for [`FooV1`]"] + pub struct FooV1Marker; + impl icu_provider::DataMarker for FooV1Marker { + type Yokeable = FooV1<'static>; + } + #[doc = "Marker type for [`FooV1`]: \"demo/bar@1\"\n\n- Fallback priority: region\n- Extension keyword: ca"] + pub struct BarV1Marker; + impl icu_provider::DataMarker for BarV1Marker { + type Yokeable = FooV1<'static>; + } + impl icu_provider::KeyedDataMarker for BarV1Marker { + const KEY: icu_provider::DataKey = icu_provider::data_key!( + "demo/bar@1", + icu_provider::DataKeyMetadata::construct_internal( + icu_provider::FallbackPriority::Region, + Some(icu_provider::_internal::extensions_unicode_key!("ca")), + Some(icu_provider::FallbackSupplement::Collation) + )); + } + #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] + pub struct FooV1<'data>; + ), + ); +} -- cgit v1.2.3