Bug 1836229 - Update serde_with to 3.0.0. r=emilio,supply-chain-reviewers

We upgrade enumset alongside so that we keep only one copy of darling.

Differential Revision: https://phabricator.services.mozilla.com/D179651
This commit is contained in:
Mike Hommey 2023-06-05 20:28:30 +00:00
Родитель c17dace30a
Коммит d0b7892964
156 изменённых файлов: 16764 добавлений и 5807 удалений

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

@ -1140,16 +1140,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.13.99"
dependencies = [
"darling 0.14.3",
]
[[package]]
name = "darling"
version = "0.14.3"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"
dependencies = [
"darling_core",
"darling_macro",
@ -1157,27 +1150,27 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.14.3"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 1.0.107",
"syn 2.0.18",
]
[[package]]
name = "darling_macro"
version = "0.14.3"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
dependencies = [
"darling_core",
"quote",
"syn 1.0.107",
"syn 2.0.18",
]
[[package]]
@ -1244,11 +1237,11 @@ dependencies = [
name = "derive_common"
version = "0.0.1"
dependencies = [
"darling 0.14.3",
"darling",
"proc-macro2",
"quote",
"syn 1.0.107",
"synstructure",
"syn 2.0.18",
"synstructure 0.13.0",
]
[[package]]
@ -1442,23 +1435,23 @@ dependencies = [
[[package]]
name = "enumset"
version = "1.0.12"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753"
checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb"
dependencies = [
"enumset_derive",
]
[[package]]
name = "enumset_derive"
version = "0.6.1"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0"
checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"
dependencies = [
"darling 0.14.3",
"darling",
"proc-macro2",
"quote",
"syn 1.0.107",
"syn 2.0.18",
]
[[package]]
@ -3069,7 +3062,7 @@ checksum = "632647502a8bfa82458c07134791fffa7a719f00427d1afd79c3cb6d4960a982"
dependencies = [
"proc-macro2",
"syn 1.0.107",
"synstructure",
"synstructure 0.12.6",
]
[[package]]
@ -3925,7 +3918,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 1.0.107",
"synstructure",
"synstructure 0.12.6",
"unicode-xid",
]
@ -4233,7 +4226,7 @@ dependencies = [
"serde",
"serde_derive",
"serde_json",
"serde_with",
"serde_with 1.999.999",
]
[[package]]
@ -4685,9 +4678,16 @@ dependencies = [
[[package]]
name = "serde_with"
version = "1.14.0"
version = "1.999.999"
dependencies = [
"serde_with 3.0.0",
]
[[package]]
name = "serde_with"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"
checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513"
dependencies = [
"serde",
"serde_with_macros",
@ -4695,14 +4695,14 @@ dependencies = [
[[package]]
name = "serde_with_macros"
version = "1.5.2"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"
checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070"
dependencies = [
"darling 0.13.99",
"darling",
"proc-macro2",
"quote",
"syn 1.0.107",
"syn 2.0.18",
]
[[package]]
@ -4966,12 +4966,12 @@ dependencies = [
name = "style_derive"
version = "0.0.1"
dependencies = [
"darling 0.14.3",
"darling",
"derive_common",
"proc-macro2",
"quote",
"syn 1.0.107",
"synstructure",
"syn 2.0.18",
"synstructure 0.13.0",
]
[[package]]
@ -5079,6 +5079,18 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "synstructure"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.18",
"unicode-xid",
]
[[package]]
name = "tabs"
version = "0.1.0"
@ -5244,12 +5256,12 @@ dependencies = [
name = "to_shmem_derive"
version = "0.0.1"
dependencies = [
"darling 0.14.3",
"darling",
"derive_common",
"proc-macro2",
"quote",
"syn 1.0.107",
"synstructure",
"syn 2.0.18",
"synstructure 0.13.0",
]
[[package]]

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

@ -102,8 +102,8 @@ bitflags = { path = "build/rust/bitflags" }
# Patch cfg-if 0.1 to 1.0
cfg-if = { path = "build/rust/cfg-if" }
# Patch darling 0.13 to 0.14
darling = { path = "build/rust/darling" }
# Patch serde_with 1.0 to 3.0
serde_with = { path = "build/rust/serde_with" }
# Patch redox_users to an empty crate
redox_users = { path = "build/rust/redox_users" }

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

@ -1,11 +0,0 @@
[package]
name = "darling"
version = "0.13.99"
edition = "2018"
license = "MPL-2.0"
[lib]
path = "lib.rs"
[dependencies.darling]
version = "0.14"

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

@ -0,0 +1,13 @@
[package]
name = "serde_with"
version = "1.999.999"
edition = "2018"
license = "MPL-2.0"
[lib]
path = "lib.rs"
[dependencies.serde_with]
version = "3"
default-features = false
features = ["macros"]

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

@ -2,4 +2,4 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
pub use darling::*;
pub use serde_with::*;

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

@ -109,6 +109,7 @@ TOLERATED_DUPES = {
"time": 2,
# Transition is underway from syn 1.x to 2.x. (bug 1835053)
"syn": 2,
"synstructure": 2,
}

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

@ -9,8 +9,8 @@ publish = false
path = "lib.rs"
[dependencies]
darling = { version = "0.14", default-features = false }
darling = { version = "0.20", default-features = false }
proc-macro2 = "1"
quote = "1"
syn = { version = "1", default-features = false, features = ["clone-impls", "parsing"] }
synstructure = "0.12"
syn = { version = "2", default-features = false, features = ["clone-impls", "parsing"] }
synstructure = "0.13"

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

@ -5,7 +5,7 @@
use darling::{FromDeriveInput, FromField, FromVariant};
use proc_macro2::{Span, TokenStream};
use quote::TokenStreamExt;
use syn::{self, AngleBracketedGenericArguments, Binding, DeriveInput, Field};
use syn::{self, AngleBracketedGenericArguments, AssocType, DeriveInput, Field};
use syn::{GenericArgument, GenericParam, Ident, Path};
use syn::{PathArguments, PathSegment, QSelf, Type, TypeArray, TypeGroup};
use syn::{TypeParam, TypeParen, TypePath, TypeSlice, TypeTuple};
@ -252,8 +252,8 @@ where
&GenericArgument::Type(ref data) => GenericArgument::Type(
map_type_params(data, params, self_type, f),
),
&GenericArgument::Binding(ref data) => {
GenericArgument::Binding(Binding {
&GenericArgument::AssocType(ref data) => {
GenericArgument::AssocType(AssocType {
ty: map_type_params(&data.ty, params, self_type, f),
..data.clone()
})

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

@ -10,9 +10,9 @@ path = "lib.rs"
proc-macro = true
[dependencies]
darling = { version = "0.14", default-features = false }
darling = { version = "0.20", default-features = false }
derive_common = { path = "../derive_common" }
proc-macro2 = "1"
quote = "1"
syn = { version = "1", default-features = false, features = ["clone-impls", "derive", "parsing"] }
synstructure = "0.12"
syn = { version = "2", default-features = false, features = ["clone-impls", "derive", "parsing"] }
synstructure = "0.13"

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

@ -10,9 +10,9 @@ path = "lib.rs"
proc-macro = true
[dependencies]
darling = { version = "0.14", default-features = false }
darling = { version = "0.20", default-features = false }
derive_common = { path = "../derive_common" }
proc-macro2 = "1"
quote = "1"
syn = { version = "1", default-features = false, features = ["derive", "parsing"] }
synstructure = "0.12"
syn = { version = "2", default-features = false, features = ["derive", "parsing"] }
synstructure = "0.13"

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

@ -958,6 +958,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.2 -> 0.14.3"
[[audits.darling]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.darling_core]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -968,6 +973,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.2 -> 0.14.3"
[[audits.darling_core]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.darling_macro]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -978,6 +988,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.2 -> 0.14.3"
[[audits.darling_macro]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.14.3 -> 0.20.1"
[[audits.data-encoding]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -1103,11 +1118,21 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.0.11 -> 1.0.12"
[[audits.enumset]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.0.12 -> 1.1.2"
[[audits.enumset_derive]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.6.0 -> 0.6.1"
[[audits.enumset_derive]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.6.1 -> 0.8.1"
[[audits.env_logger]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
@ -2542,6 +2567,16 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-run"
delta = "0.1.9 -> 0.1.10"
[[audits.serde_with]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.14.0 -> 3.0.0"
[[audits.serde_with_macros]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "1.5.2 -> 3.0.0"
[[audits.serde_yaml]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-run"
@ -2635,6 +2670,11 @@ maintainer. The one use of `unsafe` is unnecessary, but documented and
harmless. It will be removed in the next version.
"""
[[audits.synstructure]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"
delta = "0.12.6 -> 0.13.0"
[[audits.termcolor]]
who = "Mike Hommey <mh+mozilla@glandium.org>"
criteria = "safe-to-deploy"

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

@ -1 +1 @@
{"files":{"CHANGELOG.md":"36a132403864fecc7e435509e8339d9f2c0962a451c53357c1d9b08f6d8a36bc","Cargo.lock":"e77a5ba77d6ef12db6c6cdafde228004d938601f46b0bd28a0df7ca836a90142","Cargo.toml":"6ed8f0ac89f171b24a69d4da2c4e8cd711028f0463bd47e9e07026c92f92d16e","LICENSE":"8ea93490d74a5a1b1af3ff71d786271b3f1e5f0bea79ac16e02ec533cef040d6","README.md":"2147b655029789a691d4b9428c836ee55716bea250fba63b8b1c3b4b280d761c","clippy.toml":"0728f8cee5cdb954e4d5c64c9a84c83ff356a913d531412baf4b5852ba6712ef","compiletests.sh":"a255ae505d79b4a40bdc80b215a5384eadee228593d042fbed60e99cc278e220","examples/automatic_bounds.rs":"2950c8d33bb40f095decba1990d7d0bcd48dffc6e9b7cefce2fcb3818ecf1d18","examples/consume_fields.rs":"ce436936441f1f6734f47074e6625ebf64f15180b9c126a58e24aaa33613b59c","examples/fallible_read.rs":"1e5f2b69e436d899209dc8a4deec0dbe3e998f10a6632a79c0876c46f68267b4","examples/shorthand_or_long_field.rs":"ec2e2b155fd0803c80f98d0ba94e8419dd7307012ccfb916b8f752925a295d55","examples/supports_struct.rs":"08c5cc46400a0e5cf811c0d254a37b42de94b34cd04ac801069105bc792051f6","src/lib.rs":"7fb89b93193dbbab4f32327576fa49d8ba677fc32b09a36f84d3c942b2d7ea06","src/macros_public.rs":"7d2ce0c5026227ef7854db11d7a885ad891255438b2e49bbdfda56fa2f92feec","tests/accrue_errors.rs":"4f0f5be65c5cd639b107a6a14e9fb51573b27cfa9210a2182fa5f450bc1d56db","tests/compile-fail/default_expr_wrong_type.rs":"e09889ac3a243bd6096a0ef7076822b146f1481b70aae703e170ea6527071448","tests/compile-fail/default_expr_wrong_type.stderr":"dce0c05f344be36bf66407b459eb1f6abb560b6f5500d4b771d3fd5babc78325","tests/compile-fail/not_impl_from_meta.rs":"20ef167d88ea06967c26a05234d3b1787f0695d45b4ab1150bf9dc77625f9c74","tests/compile-fail/not_impl_from_meta.stderr":"3e52d37d2a5a6f98e4af70389327f9248ea283aac9bdb0660058ec92e23999b8","tests/compile-fail/skip_field_not_impl_default.rs":"5cb7e2e68d7dc42e6508eb0c170869179f127cf641b44f08f6403760f30c469b","tests/compile-fail/skip_field_not_impl_default.stderr":"664f0c2a5c3c85901b65e923b8907870bead9b2781a4c75497eb6df621a0f701","tests/compiletests.rs":"dc2b570d0e0ab4895d7cd039fa9572d507221f2ff2e546a3dacfd9c64fe1c936","tests/computed_bound.rs":"aed9c00f2b8373e9426337137207e5b9341d236adef682bd2c9427db9ce1d1ff","tests/custom_bound.rs":"9b823063b7fc6c6b3b23905405ce7f316e8a937d5c67c416b89642e537bf9110","tests/defaults.rs":"6894fded24b2f9d173b11f54bbe3b640946c6eb6f5ff5492369e8cd84fc217ef","tests/enums_newtype.rs":"ed63735b88fdfd9037580d878be895a311c13d7d8083ee3077f5ab61e754eb7c","tests/enums_struct.rs":"36ca3d4996644d566b45c78d8c343c4a74fcaa2eba96b4e012c8a1819eb6f4c6","tests/enums_unit.rs":"7f94f793e6adc265c6cdc4b657aa237da1ab0be03b03bce23d3e2180cd3e8d03","tests/error.rs":"f5f84991472e184e1167f0fe8d5f2cbad3844c4022987c9eff46b4db2bcc804a","tests/from_generics.rs":"f2c1f98f654c4e6ad3606d7b12ea7ea66782950c05da132e8d7f2f7e1bdf3af0","tests/from_meta.rs":"b9c73340c44a53a43d7234c6030d37d1ab7c63ea2ec2ae1f7f09e5f2d65baa6b","tests/from_type_param.rs":"94d2766d5ae11d69750497225d6aa3c2f34b09fbc8c3580d61f077d7bb41265b","tests/from_type_param_default.rs":"e00e2f0c779753f66b95e5c0106451f65cbd6fbc28e676381d276290da6254b6","tests/from_variant.rs":"48046b156f6c5d9b3e9c3d0b36b5eebaba1d417447e3babf81ed9c74bee3bfcb","tests/generics.rs":"0c2830acf511148d71ecd4a8b5aa17f80e377aa89f7fe0fc10f6db34671d034a","tests/happy_path.rs":"c7a540fc1755cef757aa5e6cd202a49a47a2040facb0c05c167ec62f8ebbc557","tests/hash_map.rs":"c30764bf1845ca81bc1d752dbe0de965ba70cfbb1571884a20a873ed7bf26360","tests/multiple.rs":"1362ec057f4796ffabf7161033b561b51f069b818af7bac85fe66935c62038dd","tests/newtype.rs":"b5ecf605652b194372cab6d6fef96a2dd4b63ac24649cb52ca944ef9647512ad","tests/skip.rs":"11b5f190d6eac837d4a44a7dedd1ba9e623b0c7a8bf2bdc92882e1f8a8d2aeac","tests/split_declaration.rs":"019863370414af227144aac13272fc39a1e256a9ed0bd3ca2dbf1114f1a9e1ba","tests/suggestions.rs":"e9f8ab55718a5853411a4606f1be1473b57fc7a2789f622d0ed807fcd8ac5606","tests/supports.rs":"fd27b20893a1b1078eff077d426fea7d715b8decd12ad1e0b940cfbfd4fbbfba","tests/unsupported_attributes.rs":"96333cd6602a6f18f47563d5faa923e423b2c02f2ae0d09a15e2d3514593c38d"},"package":"c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"}
{"files":{"CHANGELOG.md":"68745fb7dd94b72ba5f87271f40ee89b6a472e9a2e88153967a4add77af9ef13","Cargo.lock":"0b5e050bf93a5f957c0374aacae02aa8cf2070dc4b38a999877b7237609efae0","Cargo.toml":"1e9933d5e20abccde499d6872e07bd8be8792b673c9c008a6b38528eb7873d28","LICENSE":"8ea93490d74a5a1b1af3ff71d786271b3f1e5f0bea79ac16e02ec533cef040d6","README.md":"19aaa2e1cd8ccc8d9c344711a0e5ee3a96657d3e0c522f7a82a18b7f4865c60a","clippy.toml":"c5ef3489cce9d5ed7c766e6486a18a0a3dc0f4c677fcf05166e1d47104f6cd3f","compiletests.sh":"a255ae505d79b4a40bdc80b215a5384eadee228593d042fbed60e99cc278e220","examples/automatic_bounds.rs":"2950c8d33bb40f095decba1990d7d0bcd48dffc6e9b7cefce2fcb3818ecf1d18","examples/consume_fields.rs":"ce436936441f1f6734f47074e6625ebf64f15180b9c126a58e24aaa33613b59c","examples/fallible_read.rs":"1d081d26d1aa585b2b5ed157fc9b6562274c9c932bda3be8d8d22e2d4272a213","examples/shorthand_or_long_field.rs":"ec2e2b155fd0803c80f98d0ba94e8419dd7307012ccfb916b8f752925a295d55","examples/supports_struct.rs":"08c5cc46400a0e5cf811c0d254a37b42de94b34cd04ac801069105bc792051f6","src/lib.rs":"cbb8bb4317216ca6824c8f176f3c58effcb234b26c6b3edf1725baf0d1fcfb84","src/macros_public.rs":"7d2ce0c5026227ef7854db11d7a885ad891255438b2e49bbdfda56fa2f92feec","tests/accrue_errors.rs":"4f0f5be65c5cd639b107a6a14e9fb51573b27cfa9210a2182fa5f450bc1d56db","tests/compile-fail/default_expr_wrong_type.rs":"e09889ac3a243bd6096a0ef7076822b146f1481b70aae703e170ea6527071448","tests/compile-fail/default_expr_wrong_type.stderr":"dce0c05f344be36bf66407b459eb1f6abb560b6f5500d4b771d3fd5babc78325","tests/compile-fail/not_impl_from_meta.rs":"20ef167d88ea06967c26a05234d3b1787f0695d45b4ab1150bf9dc77625f9c74","tests/compile-fail/not_impl_from_meta.stderr":"3e52d37d2a5a6f98e4af70389327f9248ea283aac9bdb0660058ec92e23999b8","tests/compile-fail/skip_field_not_impl_default.rs":"5cb7e2e68d7dc42e6508eb0c170869179f127cf641b44f08f6403760f30c469b","tests/compile-fail/skip_field_not_impl_default.stderr":"664f0c2a5c3c85901b65e923b8907870bead9b2781a4c75497eb6df621a0f701","tests/compiletests.rs":"dc2b570d0e0ab4895d7cd039fa9572d507221f2ff2e546a3dacfd9c64fe1c936","tests/computed_bound.rs":"aed9c00f2b8373e9426337137207e5b9341d236adef682bd2c9427db9ce1d1ff","tests/custom_bound.rs":"9b823063b7fc6c6b3b23905405ce7f316e8a937d5c67c416b89642e537bf9110","tests/defaults.rs":"6894fded24b2f9d173b11f54bbe3b640946c6eb6f5ff5492369e8cd84fc217ef","tests/enums_newtype.rs":"ed63735b88fdfd9037580d878be895a311c13d7d8083ee3077f5ab61e754eb7c","tests/enums_struct.rs":"36ca3d4996644d566b45c78d8c343c4a74fcaa2eba96b4e012c8a1819eb6f4c6","tests/enums_unit.rs":"7f94f793e6adc265c6cdc4b657aa237da1ab0be03b03bce23d3e2180cd3e8d03","tests/error.rs":"f5f84991472e184e1167f0fe8d5f2cbad3844c4022987c9eff46b4db2bcc804a","tests/from_generics.rs":"8be63cc3390e94f2740932dea280c8c44d929a1fcc2cfff68cec4d3bceadc4d9","tests/from_meta.rs":"b9c73340c44a53a43d7234c6030d37d1ab7c63ea2ec2ae1f7f09e5f2d65baa6b","tests/from_type_param.rs":"94d2766d5ae11d69750497225d6aa3c2f34b09fbc8c3580d61f077d7bb41265b","tests/from_type_param_default.rs":"e00e2f0c779753f66b95e5c0106451f65cbd6fbc28e676381d276290da6254b6","tests/from_variant.rs":"48046b156f6c5d9b3e9c3d0b36b5eebaba1d417447e3babf81ed9c74bee3bfcb","tests/generics.rs":"0c2830acf511148d71ecd4a8b5aa17f80e377aa89f7fe0fc10f6db34671d034a","tests/happy_path.rs":"c7a540fc1755cef757aa5e6cd202a49a47a2040facb0c05c167ec62f8ebbc557","tests/hash_map.rs":"2559783b10108a975466b6944ed89737be6197c64a35c66cfad43a272c085a01","tests/multiple.rs":"1362ec057f4796ffabf7161033b561b51f069b818af7bac85fe66935c62038dd","tests/newtype.rs":"b5ecf605652b194372cab6d6fef96a2dd4b63ac24649cb52ca944ef9647512ad","tests/skip.rs":"11b5f190d6eac837d4a44a7dedd1ba9e623b0c7a8bf2bdc92882e1f8a8d2aeac","tests/split_declaration.rs":"019863370414af227144aac13272fc39a1e256a9ed0bd3ca2dbf1114f1a9e1ba","tests/suggestions.rs":"e9f8ab55718a5853411a4606f1be1473b57fc7a2789f622d0ed807fcd8ac5606","tests/supports.rs":"fd27b20893a1b1078eff077d426fea7d715b8decd12ad1e0b940cfbfd4fbbfba","tests/unsupported_attributes.rs":"84ba14c2762c3ad4432c238000a03b70b3bf1a4565d604ba00d0346952c3f6bb"},"package":"0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944"}

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

@ -1,5 +1,48 @@
# Changelog
## v0.20.1 (May 2, 2023)
- Add `Clone` impl for `NestedMeta` [#230](https://github.com/TedDriggs/darling/pull/230)
## v0.20.0 (April 27, 2023)
- Bump syn to version 2, courtesy of @jonasbb [#227](https://github.com/TedDriggs/darling/issues/227)
### Breaking Changes
- Replace all occurrences of syn::NestedMeta with darling::ast::NestedMeta.
- Replacement for the deprecated AttributeArgs:
```rust
// Before
parse_macro_input!(args as AttributeArgs);
// After
match NestedMeta::parse_meta_list(args) {
Ok(v) => v,
Err(e) => {
return TokenStream::from(Error::from(e).write_errors());
}
};
```
- In GenericParamExt, `LifetimeDef` is now `LifetimeParam`.
- In GenericParamExt, `as_lifetime_def` is renamed to `as_lifetime_param`.
- Flag and SpannedValue no longer implement `syn::spanned::Spanned`.
- The MSRV (minimum supported Rust version) is now 1.56, because of syn.
### Deprecation Warnings
In previous versions of `darling`, arbitrary expressions were passed in attributes by wrapping them in quotation marks.
v0.20.0 preserves this behavior for `syn::Expr`, but as a result a field expecting a `syn::Expr` cannot accept a string literal - it will incorrectly attempt to parse the contents. If this is an issue for you, please add a comment to [#229](https://github.com/TedDriggs/darling/issues/229).
## v0.14.4 (March 9, 2023)
- Add support for child diagnostics when `diagnostics` feature enabled [#224](https://github.com/TedDriggs/darling/issues/224)
## v0.14.3 (February 3, 2023)
- Re-export `syn` from `darling` to avoid requiring that consuming crates have a `syn` dependency.

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

@ -4,40 +4,40 @@ version = 3
[[package]]
name = "darling"
version = "0.14.3"
version = "0.20.1"
dependencies = [
"darling_core",
"darling_macro",
"proc-macro2",
"quote",
"rustversion",
"syn",
"syn 2.0.15",
"trybuild",
]
[[package]]
name = "darling_core"
version = "0.14.3"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
"syn 2.0.15",
]
[[package]]
name = "darling_macro"
version = "0.14.3"
version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"
dependencies = [
"darling_core",
"quote",
"syn",
"syn 2.0.15",
]
[[package]]
@ -72,18 +72,18 @@ checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "proc-macro2"
version = "1.0.37"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.18"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
@ -114,7 +114,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.91",
]
[[package]]
@ -145,6 +145,17 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "syn"
version = "2.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "termcolor"
version = "1.1.3"
@ -178,6 +189,12 @@ dependencies = [
"toml",
]
[[package]]
name = "unicode-ident"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "unicode-xid"
version = "0.2.2"

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

@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "darling"
version = "0.14.3"
version = "0.20.1"
authors = ["Ted Driggs <ted.driggs@outlook.com>"]
exclude = [
"/.travis.yml",
@ -23,16 +23,16 @@ description = """
A proc-macro library for reading attributes into structs when
implementing custom derives.
"""
documentation = "https://docs.rs/darling/0.14.3"
documentation = "https://docs.rs/darling/0.20.1"
readme = "README.md"
license = "MIT"
repository = "https://github.com/TedDriggs/darling"
[dependencies.darling_core]
version = "=0.14.3"
version = "=0.20.1"
[dependencies.darling_macro]
version = "=0.14.3"
version = "=0.20.1"
[dev-dependencies.proc-macro2]
version = "1.0.37"
@ -41,7 +41,7 @@ version = "1.0.37"
version = "1.0.18"
[dev-dependencies.syn]
version = "1.0.91"
version = "2.0.15"
[features]
default = ["suggestions"]

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

@ -1,17 +1,18 @@
Darling
=======
# Darling
[![Build Status](https://github.com/TedDriggs/darling/workflows/CI/badge.svg)](https://github.com/TedDriggs/darling/actions)
[![Latest Version](https://img.shields.io/crates/v/darling.svg)](https://crates.io/crates/darling)
[![Rustc Version 1.31+](https://img.shields.io/badge/rustc-1.31+-lightgray.svg)](https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html)
[![Rustc Version 1.56+](https://img.shields.io/badge/rustc-1.56+-lightgray.svg)]
`darling` is a crate for proc macro authors, which enables parsing attributes into structs. It is heavily inspired by `serde` both in its internals and in its API.
# Benefits
* Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment.
* Great validation and errors, no work required. When users of your proc-macro make a mistake, `darling` makes sure they get error markers at the right place in their source, and provides "did you mean" suggestions for misspelled fields.
- Easy and declarative parsing of macro input - make your proc-macros highly controllable with minimal time investment.
- Great validation and errors, no work required. When users of your proc-macro make a mistake, `darling` makes sure they get error markers at the right place in their source, and provides "did you mean" suggestions for misspelled fields.
# Usage
`darling` provides a set of traits which can be derived or manually implemented.
1. `FromMeta` is used to extract values from a meta-item in an attribute. Implementations are likely reusable for many libraries, much like `FromStr` or `serde::Deserialize`. Trait implementations are provided for primitives, some std types, and some `syn` types.
@ -21,9 +22,10 @@ Darling
5. `FromAttributes` is a lower-level version of the more-specific `FromDeriveInput`, `FromField`, and `FromVariant` traits. Structs deriving this trait get a meta-item extractor and error collection which works for any syntax element, including traits, trait items, and functions. This is useful for non-derive proc macros.
## Additional Modules
* `darling::ast` provides generic types for representing the AST.
* `darling::usage` provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum.
* `darling::util` provides helper types with special `FromMeta` implementations, such as `IdentList`.
- `darling::ast` provides generic types for representing the AST.
- `darling::usage` provides traits and functions for determining where type parameters and lifetimes are used in a struct or enum.
- `darling::util` provides helper types with special `FromMeta` implementations, such as `IdentList`.
# Example
@ -59,14 +61,17 @@ pub struct ConsumingType;
```
# Attribute Macros
Non-derive attribute macros are supported.
To parse arguments for attribute macros, derive `FromMeta` on the argument receiver type, then pass `&syn::AttributeArgs` to the `from_list` method.
This will produce a normal `darling::Result<T>` that can be used the same as a result from parsing a `DeriveInput`.
## Macro Code
```rust,ignore
use darling::FromMeta;
use syn::{AttributeArgs, ItemFn};
use darling::{Error, FromMeta};
use darling::ast::NestedMeta;
use syn::ItemFn;
use proc_macro::TokenStream;
#[derive(Debug, FromMeta)]
@ -76,10 +81,13 @@ pub struct MacroArgs {
path: String,
}
#[proc_macro_attribute]
// #[proc_macro_attribute]
fn your_attr(args: TokenStream, input: TokenStream) -> TokenStream {
let attr_args = parse_macro_input!(args as AttributeArgs);
let _input = parse_macro_input!(input as ItemFn);
let attr_args = match NestedMeta::parse_meta_list(args) {
Ok(v) => v,
Err(e) => { return TokenStream::from(Error::from(e).write_errors()); }
};
let _input = syn::parse_macro_input!(input as ItemFn);
let _args = match MacroArgs::from_list(&attr_args) {
Ok(v) => v,
@ -92,6 +100,7 @@ fn your_attr(args: TokenStream, input: TokenStream) -> TokenStream {
```
## Consuming Code
```rust,ignore
use your_crate::your_attr;
@ -102,37 +111,39 @@ fn do_stuff() {
```
# Features
Darling's features are built to work well for real-world projects.
* **Defaults**: Supports struct- and field-level defaults, using the same path syntax as `serde`.
Additionally, `Option<T>` and `darling::util::Flag` fields are innately optional; you don't need to declare `#[darling(default)]` for those.
* **Field Renaming**: Fields can have different names in usage vs. the backing code.
* **Auto-populated fields**: Structs deriving `FromDeriveInput` and `FromField` can declare properties named `ident`, `vis`, `ty`, `attrs`, and `generics` to automatically get copies of the matching values from the input AST. `FromDeriveInput` additionally exposes `data` to get access to the body of the deriving type, and `FromVariant` exposes `fields`.
* **Mapping function**: Use `#[darling(map="path")]` or `#[darling(and_then="path")]` to specify a function that runs on the result of parsing a meta-item field. This can change the return type, which enables you to parse to an intermediate form and convert that to the type you need in your struct.
* **Skip fields**: Use `#[darling(skip)]` to mark a field that shouldn't be read from attribute meta-items.
* **Multiple-occurrence fields**: Use `#[darling(multiple)]` on a `Vec` field to allow that field to appear multiple times in the meta-item. Each occurrence will be pushed into the `Vec`.
* **Span access**: Use `darling::util::SpannedValue` in a struct to get access to that meta item's source code span. This can be used to emit warnings that point at a specific field from your proc macro. In addition, you can use `darling::Error::write_errors` to automatically get precise error location details in most cases.
* **"Did you mean" suggestions**: Compile errors from derived darling trait impls include suggestions for misspelled fields.
- **Defaults**: Supports struct- and field-level defaults, using the same path syntax as `serde`.
Additionally, `Option<T>` and `darling::util::Flag` fields are innately optional; you don't need to declare `#[darling(default)]` for those.
- **Field Renaming**: Fields can have different names in usage vs. the backing code.
- **Auto-populated fields**: Structs deriving `FromDeriveInput` and `FromField` can declare properties named `ident`, `vis`, `ty`, `attrs`, and `generics` to automatically get copies of the matching values from the input AST. `FromDeriveInput` additionally exposes `data` to get access to the body of the deriving type, and `FromVariant` exposes `fields`.
- **Mapping function**: Use `#[darling(map="path")]` or `#[darling(and_then="path")]` to specify a function that runs on the result of parsing a meta-item field. This can change the return type, which enables you to parse to an intermediate form and convert that to the type you need in your struct.
- **Skip fields**: Use `#[darling(skip)]` to mark a field that shouldn't be read from attribute meta-items.
- **Multiple-occurrence fields**: Use `#[darling(multiple)]` on a `Vec` field to allow that field to appear multiple times in the meta-item. Each occurrence will be pushed into the `Vec`.
- **Span access**: Use `darling::util::SpannedValue` in a struct to get access to that meta item's source code span. This can be used to emit warnings that point at a specific field from your proc macro. In addition, you can use `darling::Error::write_errors` to automatically get precise error location details in most cases.
- **"Did you mean" suggestions**: Compile errors from derived darling trait impls include suggestions for misspelled fields.
## Shape Validation
Some proc-macros only work on structs, while others need enums whose variants are either unit or newtype variants.
Darling makes this sort of validation extremely simple.
On the receiver that derives `FromDeriveInput`, add `#[darling(supports(...))]` and then list the shapes that your macro should accept.
|Name|Description|
|---|---|
|`any`|Accept anything|
|`struct_any`|Accept any struct|
|`struct_named`|Accept structs with named fields, e.g. `struct Example { field: String }`|
|`struct_newtype`|Accept newtype structs, e.g. `struct Example(String)`|
|`struct_tuple`|Accept tuple structs, e.g. `struct Example(String, String)`|
|`struct_unit`|Accept unit structs, e.g. `struct Example;`|
|`enum_any`|Accept any enum|
|`enum_named`|Accept enum variants with named fields|
|`enum_newtype`|Accept newtype enum variants|
|`enum_tuple`|Accept tuple enum variants|
|`enum_unit`|Accept unit enum variants|
| Name | Description |
| ---------------- | ------------------------------------------------------------------------- |
| `any` | Accept anything |
| `struct_any` | Accept any struct |
| `struct_named` | Accept structs with named fields, e.g. `struct Example { field: String }` |
| `struct_newtype` | Accept newtype structs, e.g. `struct Example(String)` |
| `struct_tuple` | Accept tuple structs, e.g. `struct Example(String, String)` |
| `struct_unit` | Accept unit structs, e.g. `struct Example;` |
| `enum_any` | Accept any enum |
| `enum_named` | Accept enum variants with named fields |
| `enum_newtype` | Accept newtype enum variants |
| `enum_tuple` | Accept tuple enum variants |
| `enum_unit` | Accept unit enum variants |
Each one is additive, so listing `#[darling(supports(struct_any, enum_newtype))]` would accept all structs and any enum where every variant is a newtype variant.
This can also be used when deriving `FromVariant`, without the `enum_` prefix.
This can also be used when deriving `FromVariant`, without the `enum_` prefix.

2
third_party/rust/darling/clippy.toml поставляемый
Просмотреть файл

@ -1,2 +1,2 @@
msrv = "1.31.0"
msrv = "1.56.0"
disallowed-names = [] # we want to be able to use placeholder names in tests

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

@ -51,7 +51,7 @@ impl MyInputReceiver {
// we'll go ahead and make it positive.
let amplitude = match amplitude {
Ok(amp) => amp,
Err(mi) => (i64::from_meta(&mi)?).abs() as u64,
Err(mi) => (i64::from_meta(&mi)?).unsigned_abs(),
};
Ok(Self {

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

@ -102,6 +102,8 @@ pub mod export {
pub use darling_core::syn;
pub use std::string::ToString;
pub use std::vec::Vec;
pub use crate::ast::NestedMeta;
}
#[macro_use]

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

@ -48,8 +48,8 @@ fn expand_some() {
.expect("Input is well-formed");
assert!(rec.generics.where_clause.is_none());
// Make sure we've preserved the lifetime def, though we don't do anything with it.
assert!(rec.generics.params[0].as_lifetime_def().is_some());
// Make sure we've preserved the lifetime param, though we don't do anything with it.
assert!(rec.generics.params[0].as_lifetime_param().is_some());
let mut ty_param_iter = rec.generics.type_params();

2
third_party/rust/darling/tests/hash_map.rs поставляемый
Просмотреть файл

@ -16,7 +16,7 @@ fn parse_map() {
#[foo(first(name = "Hello", option), the::second(name = "Second"))]
};
let meta = attr.parse_meta().unwrap();
let meta = attr.meta;
let map: HashMap<Path, MapValue> = FromMeta::from_meta(&meta).unwrap();
let comparison: HashMap<Path, MapValue> = vec![

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

@ -20,8 +20,8 @@ fn non_meta_attribute_gets_own_error() {
};
let errors: darling::Error = Bar::from_derive_input(&di).unwrap_err().flatten();
// The number of errors here is 1 for the bad attribute + 2 for the missing fields
assert_eq!(3, errors.len());
// The number of errors here is 1 for the bad value of the `st` attribute
assert_eq!(1, errors.len());
// Make sure one of the errors propagates the syn error
assert!(errors
.into_iter()
@ -40,8 +40,8 @@ fn non_meta_attribute_does_not_block_others() {
};
let errors: darling::Error = Bar::from_derive_input(&di).unwrap_err().flatten();
// The number of errors here is 1 for the bad attribute + 1 for the missing "st" field
assert_eq!(2, errors.len());
// The number of errors here is 1 for the bad value of the `st` attribute
assert_eq!(1, errors.len());
// Make sure one of the errors propagates the syn error
assert!(errors
.into_iter()

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

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

@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "darling_core"
version = "0.14.3"
version = "0.20.1"
authors = ["Ted Driggs <ted.driggs@outlook.com>"]
description = """
Helper crate for proc-macro library for reading attributes into structs when
@ -38,7 +38,7 @@ version = "0.10.0"
optional = true
[dependencies.syn]
version = "1.0.91"
version = "2.0.15"
features = [
"full",
"extra-traits",

40
third_party/rust/darling_core/src/ast/data.rs поставляемый
Просмотреть файл

@ -2,7 +2,10 @@ use std::{slice, vec};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned, ToTokens};
use syn::ext::IdentExt;
use syn::parse::Parser;
use syn::spanned::Spanned;
use syn::Token;
use crate::usage::{
self, IdentRefSet, IdentSet, LifetimeRefSet, LifetimeSet, UsesLifetimes, UsesTypeParams,
@ -410,6 +413,43 @@ impl<'a> From<&'a syn::Fields> for Style {
}
}
#[derive(Debug, Clone)]
pub enum NestedMeta {
Meta(syn::Meta),
Lit(syn::Lit),
}
impl NestedMeta {
pub fn parse_meta_list(tokens: TokenStream) -> syn::Result<Vec<Self>> {
syn::punctuated::Punctuated::<NestedMeta, Token![,]>::parse_terminated
.parse2(tokens)
.map(|punctuated| punctuated.into_iter().collect())
}
}
impl syn::parse::Parse for NestedMeta {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
if input.peek(syn::Lit) && !(input.peek(syn::LitBool) && input.peek2(Token![=])) {
input.parse().map(NestedMeta::Lit)
} else if input.peek(syn::Ident::peek_any)
|| input.peek(Token![::]) && input.peek3(syn::Ident::peek_any)
{
input.parse().map(NestedMeta::Meta)
} else {
Err(input.error("expected identifier or literal"))
}
}
}
impl ToTokens for NestedMeta {
fn to_tokens(&self, tokens: &mut TokenStream) {
match self {
NestedMeta::Meta(meta) => meta.to_tokens(tokens),
NestedMeta::Lit(lit) => lit.to_tokens(tokens),
}
}
}
#[cfg(test)]
mod tests {
use super::*;

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

@ -14,7 +14,7 @@ use crate::{FromGenericParam, FromGenerics, FromTypeParam, Result};
pub trait GenericParamExt {
/// The type this GenericParam uses to represent type params and their bounds
type TypeParam;
type LifetimeDef;
type LifetimeParam;
type ConstParam;
/// If this GenericParam is a type param, get the underlying value.
@ -23,7 +23,7 @@ pub trait GenericParamExt {
}
/// If this GenericParam is a lifetime, get the underlying value.
fn as_lifetime_def(&self) -> Option<&Self::LifetimeDef> {
fn as_lifetime_param(&self) -> Option<&Self::LifetimeParam> {
None
}
@ -35,7 +35,7 @@ pub trait GenericParamExt {
impl GenericParamExt for syn::GenericParam {
type TypeParam = syn::TypeParam;
type LifetimeDef = syn::LifetimeDef;
type LifetimeParam = syn::LifetimeParam;
type ConstParam = syn::ConstParam;
fn as_type_param(&self) -> Option<&Self::TypeParam> {
@ -46,7 +46,7 @@ impl GenericParamExt for syn::GenericParam {
}
}
fn as_lifetime_def(&self) -> Option<&Self::LifetimeDef> {
fn as_lifetime_param(&self) -> Option<&Self::LifetimeParam> {
if let syn::GenericParam::Lifetime(ref val) = *self {
Some(val)
} else {
@ -65,7 +65,7 @@ impl GenericParamExt for syn::GenericParam {
impl GenericParamExt for syn::TypeParam {
type TypeParam = syn::TypeParam;
type LifetimeDef = ();
type LifetimeParam = ();
type ConstParam = ();
fn as_type_param(&self) -> Option<&Self::TypeParam> {
@ -75,7 +75,7 @@ impl GenericParamExt for syn::TypeParam {
/// A mirror of `syn::GenericParam` which is generic over all its contents.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum GenericParam<T = syn::TypeParam, L = syn::LifetimeDef, C = syn::ConstParam> {
pub enum GenericParam<T = syn::TypeParam, L = syn::LifetimeParam, C = syn::ConstParam> {
Type(T),
Lifetime(L),
Const(C),
@ -103,7 +103,7 @@ impl<T: FromTypeParam> FromGenericParam for GenericParam<T> {
impl<T, L, C> GenericParamExt for GenericParam<T, L, C> {
type TypeParam = T;
type LifetimeDef = L;
type LifetimeParam = L;
type ConstParam = C;
fn as_type_param(&self) -> Option<&T> {
@ -114,7 +114,7 @@ impl<T, L, C> GenericParamExt for GenericParam<T, L, C> {
}
}
fn as_lifetime_def(&self) -> Option<&L> {
fn as_lifetime_param(&self) -> Option<&L> {
if let GenericParam::Lifetime(ref val) = *self {
Some(val)
} else {

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

@ -55,13 +55,18 @@ pub trait ExtractAttribute {
#(#attr_names)|* => {
match ::darling::util::parse_attribute_to_meta_list(__attr) {
::darling::export::Ok(__data) => {
if __data.nested.is_empty() {
continue;
match ::darling::export::NestedMeta::parse_meta_list(__data.tokens) {
::darling::export::Ok(ref __items) => {
if __items.is_empty() {
continue;
}
#core_loop
}
::darling::export::Err(__err) => {
__errors.push(__err.into());
}
}
let __items = &__data.nested;
#core_loop
}
// darling was asked to handle this attribute name, but the actual attribute
// isn't one that darling can work with. This either indicates a typing error
@ -92,7 +97,7 @@ pub trait ExtractAttribute {
for __attr in #attrs_accessor {
// Filter attributes based on name
match ::darling::export::ToString::to_string(&__attr.path.clone().into_token_stream()).as_str() {
match ::darling::export::ToString::to_string(&__attr.path().clone().into_token_stream()).as_str() {
#parse_handled
#forward_unhandled
}

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

@ -55,7 +55,7 @@ impl<'a> ToTokens for FromMetaImpl<'a> {
let post_transform = base.post_transform_call();
quote!(
fn from_list(__items: &[::darling::export::syn::NestedMeta]) -> ::darling::Result<Self> {
fn from_list(__items: &[::darling::export::NestedMeta]) -> ::darling::Result<Self> {
#decls
@ -91,13 +91,13 @@ impl<'a> ToTokens for FromMetaImpl<'a> {
};
quote!(
fn from_list(__outer: &[::darling::export::syn::NestedMeta]) -> ::darling::Result<Self> {
fn from_list(__outer: &[::darling::export::NestedMeta]) -> ::darling::Result<Self> {
// An enum must have exactly one value inside the parentheses if it's not a unit
// match arm
match __outer.len() {
0 => ::darling::export::Err(::darling::Error::too_few_items(1)),
1 => {
if let ::darling::export::syn::NestedMeta::Meta(ref __nested) = __outer[0] {
if let ::darling::export::NestedMeta::Meta(ref __nested) = __outer[0] {
match ::darling::util::path_to_string(__nested.path()).as_ref() {
#(#struct_arms)*
__other => ::darling::export::Err(::darling::Error::#unknown_variant_err.with_span(__nested))

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

@ -121,7 +121,8 @@ impl<'a> ToTokens for DataMatchArm<'a> {
tokens.append_all(quote!(
#name_in_attr => {
if let ::darling::export::syn::Meta::List(ref __data) = *__nested {
let __items = &__data.nested;
let __items = ::darling::export::NestedMeta::parse_meta_list(__data.tokens.clone())?;
let __items = &__items;
#declare_errors

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

@ -60,14 +60,14 @@ impl<'a> FieldsGen<'a> {
quote!(
for __item in __items {
match *__item {
::darling::export::syn::NestedMeta::Meta(ref __inner) => {
::darling::export::NestedMeta::Meta(ref __inner) => {
let __name = ::darling::util::path_to_string(__inner.path());
match __name.as_str() {
#(#arms)*
__other => { #handle_unknown }
}
}
::darling::export::syn::NestedMeta::Lit(ref __inner) => {
::darling::export::NestedMeta::Lit(ref __inner) => {
__errors.push(::darling::Error::unsupported_format("literal")
.with_span(__inner));
}

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

@ -0,0 +1,82 @@
use proc_macro2::Span;
/// Exhaustive mirror of [`proc_macro::Level`].
#[derive(Debug, Clone)]
pub(in crate::error) enum Level {
Error,
Warning,
Note,
Help,
}
/// Supplemental message for an [`Error`](super::Error) when it's emitted as a `Diagnostic`.
///
/// # Example Output
/// The `note` and `help` lines below come from child diagnostics.
///
/// ```text
/// error: My custom error
/// --> my_project/my_file.rs:3:5
/// |
/// 13 | FooBar { value: String },
/// | ^^^^^^
/// |
/// = note: My note on the macro usage
/// = help: Try doing this instead
/// ```
#[derive(Debug, Clone)]
pub(in crate::error) struct ChildDiagnostic {
level: Level,
span: Option<Span>,
message: String,
}
impl ChildDiagnostic {
pub(in crate::error) fn new(level: Level, span: Option<Span>, message: String) -> Self {
Self {
level,
span,
message,
}
}
}
impl ChildDiagnostic {
/// Append this child diagnostic to a `Diagnostic`.
///
/// # Panics
/// This method panics if `self` has a span and is being invoked outside of
/// a proc-macro due to the behavior of [`Span::unwrap()`](Span).
pub fn append_to(self, diagnostic: proc_macro::Diagnostic) -> proc_macro::Diagnostic {
match self.level {
Level::Error => {
if let Some(span) = self.span {
diagnostic.span_error(span.unwrap(), self.message)
} else {
diagnostic.error(self.message)
}
}
Level::Warning => {
if let Some(span) = self.span {
diagnostic.span_warning(span.unwrap(), self.message)
} else {
diagnostic.warning(self.message)
}
}
Level::Note => {
if let Some(span) = self.span {
diagnostic.span_note(span.unwrap(), self.message)
} else {
diagnostic.note(self.message)
}
}
Level::Help => {
if let Some(span) = self.span {
diagnostic.span_help(span.unwrap(), self.message)
} else {
diagnostic.help(self.message)
}
}
}
}
}

164
third_party/rust/darling_core/src/error/mod.rs поставляемый
Просмотреть файл

@ -13,8 +13,10 @@ use std::iter::{self, Iterator};
use std::string::ToString;
use std::vec;
use syn::spanned::Spanned;
use syn::{Lit, LitStr, Path};
use syn::{Expr, Lit, LitStr, Path};
#[cfg(feature = "diagnostics")]
mod child;
mod kind;
use crate::util::path_to_string;
@ -62,6 +64,9 @@ pub struct Error {
locations: Vec<String>,
/// The span to highlight in the emitted diagnostic.
span: Option<Span>,
/// Additional diagnostic messages to show with the error.
#[cfg(feature = "diagnostics")]
children: Vec<child::ChildDiagnostic>,
}
/// Error creation functions
@ -71,6 +76,8 @@ impl Error {
kind,
locations: Vec::new(),
span: None,
#[cfg(feature = "diagnostics")]
children: vec![],
}
}
@ -142,6 +149,53 @@ impl Error {
Error::new(ErrorKind::UnexpectedType(ty.into()))
}
pub fn unexpected_expr_type(expr: &Expr) -> Self {
Error::unexpected_type(match *expr {
Expr::Array(_) => "array",
Expr::Assign(_) => "assign",
Expr::Async(_) => "async",
Expr::Await(_) => "await",
Expr::Binary(_) => "binary",
Expr::Block(_) => "block",
Expr::Break(_) => "break",
Expr::Call(_) => "call",
Expr::Cast(_) => "cast",
Expr::Closure(_) => "closure",
Expr::Const(_) => "const",
Expr::Continue(_) => "continue",
Expr::Field(_) => "field",
Expr::ForLoop(_) => "for_loop",
Expr::Group(_) => "group",
Expr::If(_) => "if",
Expr::Index(_) => "index",
Expr::Infer(_) => "infer",
Expr::Let(_) => "let",
Expr::Lit(_) => "lit",
Expr::Loop(_) => "loop",
Expr::Macro(_) => "macro",
Expr::Match(_) => "match",
Expr::MethodCall(_) => "method_call",
Expr::Paren(_) => "paren",
Expr::Path(_) => "path",
Expr::Range(_) => "range",
Expr::Reference(_) => "reference",
Expr::Repeat(_) => "repeat",
Expr::Return(_) => "return",
Expr::Struct(_) => "struct",
Expr::Try(_) => "try",
Expr::TryBlock(_) => "try_block",
Expr::Tuple(_) => "tuple",
Expr::Unary(_) => "unary",
Expr::Unsafe(_) => "unsafe",
Expr::Verbatim(_) => "verbatim",
Expr::While(_) => "while",
Expr::Yield(_) => "yield",
// non-exhaustive enum
_ => "unknown",
})
.with_span(expr)
}
/// Creates a new error for a field which has an unexpected literal type. This will automatically
/// extract the literal type name from the passed-in `Lit` and set the span to encompass only the
/// literal value.
@ -181,6 +235,8 @@ impl Error {
Lit::Float(_) => "float",
Lit::Bool(_) => "bool",
Lit::Verbatim(_) => "verbatim",
// non-exhaustive enum
_ => "unknown",
})
.with_span(lit)
}
@ -276,18 +332,36 @@ impl Error {
}
/// Recursively converts a tree of errors to a flattened list.
///
/// # Child Diagnostics
/// If the `diagnostics` feature is enabled, any child diagnostics on `self`
/// will be cloned down to all the errors within `self`.
pub fn flatten(self) -> Self {
Error::multiple(self.into_vec())
}
fn into_vec(self) -> Vec<Self> {
if let ErrorKind::Multiple(errors) = self.kind {
let mut flat = Vec::new();
for error in errors {
flat.extend(error.prepend_at(self.locations.clone()).into_vec());
}
let locations = self.locations;
flat
#[cfg(feature = "diagnostics")]
let children = self.children;
errors
.into_iter()
.flat_map(|error| {
// This is mutated if the diagnostics feature is enabled
#[allow(unused_mut)]
let mut error = error.prepend_at(locations.clone());
// Any child diagnostics in `self` are cloned down to all the distinct
// errors contained in `self`.
#[cfg(feature = "diagnostics")]
error.children.extend(children.iter().cloned());
error.into_vec()
})
.collect()
} else {
vec![self]
}
@ -371,13 +445,17 @@ impl Error {
//
// If span information is available, don't include the error property path
// since it's redundant and not consistent with native compiler diagnostics.
match self.kind {
let diagnostic = match self.kind {
ErrorKind::UnknownField(euf) => euf.into_diagnostic(self.span),
_ => match self.span {
Some(span) => span.unwrap().error(self.kind.to_string()),
None => Diagnostic::new(Level::Error, self.to_string()),
},
}
};
self.children
.into_iter()
.fold(diagnostic, |out, child| child.append_to(out))
}
/// Transform this error and its children into a list of compiler diagnostics
@ -419,6 +497,76 @@ impl Error {
}
}
#[cfg(feature = "diagnostics")]
macro_rules! add_child {
($unspanned:ident, $spanned:ident, $level:ident) => {
#[doc = concat!("Add a child ", stringify!($unspanned), " message to this error.")]
#[doc = "# Example"]
#[doc = "```rust"]
#[doc = "# use darling_core::Error;"]
#[doc = concat!(r#"Error::custom("Example")."#, stringify!($unspanned), r#"("message content");"#)]
#[doc = "```"]
pub fn $unspanned<T: fmt::Display>(mut self, message: T) -> Self {
self.children.push(child::ChildDiagnostic::new(
child::Level::$level,
None,
message.to_string(),
));
self
}
#[doc = concat!("Add a child ", stringify!($unspanned), " message to this error with its own span.")]
#[doc = "# Example"]
#[doc = "```rust"]
#[doc = "# use darling_core::Error;"]
#[doc = "# let item_to_span = proc_macro2::Span::call_site();"]
#[doc = concat!(r#"Error::custom("Example")."#, stringify!($spanned), r#"(&item_to_span, "message content");"#)]
#[doc = "```"]
pub fn $spanned<S: Spanned, T: fmt::Display>(mut self, span: &S, message: T) -> Self {
self.children.push(child::ChildDiagnostic::new(
child::Level::$level,
Some(span.span()),
message.to_string(),
));
self
}
};
}
/// Add child diagnostics to the error.
///
/// # Example
///
/// ## Code
///
/// ```rust
/// # use darling_core::Error;
/// # let struct_ident = proc_macro2::Span::call_site();
/// Error::custom("this is a demo")
/// .with_span(&struct_ident)
/// .note("we wrote this")
/// .help("try doing this instead");
/// ```
/// ## Output
///
/// ```text
/// error: this is a demo
/// --> my_project/my_file.rs:3:5
/// |
/// 13 | FooBar { value: String },
/// | ^^^^^^
/// |
/// = note: we wrote this
/// = help: try doing this instead
/// ```
#[cfg(feature = "diagnostics")]
impl Error {
add_child!(error, span_error, Error);
add_child!(warning, span_warning, Warning);
add_child!(note, span_note, Note);
add_child!(help, span_help, Help);
}
impl StdError for Error {
fn description(&self) -> &str {
self.kind.description()

132
third_party/rust/darling_core/src/from_meta.rs поставляемый
Просмотреть файл

@ -7,9 +7,11 @@ use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use syn::{Expr, Lit, Meta, NestedMeta};
use syn::{Expr, Lit, Meta};
use crate::{util::path_to_string, Error, Result};
use crate::ast::NestedMeta;
use crate::util::path_to_string;
use crate::{Error, Result};
/// Create an instance from an item in an attribute declaration.
///
@ -66,14 +68,10 @@ pub trait FromMeta: Sized {
fn from_meta(item: &Meta) -> Result<Self> {
(match *item {
Meta::Path(_) => Self::from_word(),
Meta::List(ref value) => Self::from_list(
&value
.nested
.iter()
.cloned()
.collect::<Vec<syn::NestedMeta>>()[..],
),
Meta::NameValue(ref value) => Self::from_value(&value.lit),
Meta::List(ref value) => {
Self::from_list(&NestedMeta::parse_meta_list(value.tokens.clone())?[..])
}
Meta::NameValue(ref value) => Self::from_expr(&value.value),
})
.map_err(|e| e.with_span(item))
}
@ -121,6 +119,15 @@ pub trait FromMeta: Sized {
.map_err(|e| e.with_span(value))
}
fn from_expr(expr: &Expr) -> Result<Self> {
match *expr {
Expr::Lit(ref lit) => Self::from_value(&lit.lit),
Expr::Group(ref group) => Self::from_expr(&group.expr),
_ => Err(Error::unexpected_expr_type(expr)),
}
.map_err(|e| e.with_span(expr))
}
/// Create an instance from a char literal in a value position.
#[allow(unused_variables)]
fn from_char(value: char) -> Result<Self> {
@ -267,6 +274,74 @@ impl<T: syn::parse::Parse, P: syn::parse::Parse> FromMeta for syn::punctuated::P
}
}
/// Support for arbitrary expressions as values in a meta item.
///
/// For backwards-compatibility to versions of `darling` based on `syn` 1,
/// string literals will be "unwrapped" and their contents will be parsed
/// as an expression.
impl FromMeta for syn::Expr {
fn from_expr(expr: &Expr) -> Result<Self> {
if let syn::Expr::Lit(expr_lit) = expr {
if let syn::Lit::Str(_) = &expr_lit.lit {
return Self::from_value(&expr_lit.lit);
}
}
Ok(expr.clone())
}
fn from_string(value: &str) -> Result<Self> {
syn::parse_str(value).map_err(|_| Error::unknown_value(value))
}
fn from_value(value: &::syn::Lit) -> Result<Self> {
if let ::syn::Lit::Str(ref v) = *value {
v.parse::<syn::Expr>()
.map_err(|_| Error::unknown_lit_str_value(v))
} else {
Err(Error::unexpected_lit_type(value))
}
}
}
/// Adapter for various expression types.
///
/// Prior to syn 2.0, darling supported arbitrary expressions as long as they
/// were wrapped in quotation marks. This was helpful for people writing
/// libraries that needed expressions, but it now creates an ambiguity when
/// parsing a meta item.
///
/// To address this, the macro supports both formats; if it cannot parse the
/// item as an expression of the right type and the passed-in expression is
/// a string literal, it will fall back to parsing the string contents.
macro_rules! from_syn_expr_type {
($ty:path, $variant:ident) => {
impl FromMeta for $ty {
fn from_expr(expr: &syn::Expr) -> Result<Self> {
if let syn::Expr::$variant(body) = expr {
Ok(body.clone())
} else if let syn::Expr::Lit(expr_lit) = expr {
Self::from_value(&expr_lit.lit)
} else {
Err(Error::unexpected_expr_type(expr))
}
}
fn from_value(value: &::syn::Lit) -> Result<Self> {
if let syn::Lit::Str(body) = &value {
body.parse::<$ty>()
.map_err(|_| Error::unknown_lit_str_value(body))
} else {
Err(Error::unexpected_lit_type(value))
}
}
}
};
}
from_syn_expr_type!(syn::ExprArray, Array);
from_syn_expr_type!(syn::ExprPath, Path);
/// Adapter from `syn::parse::Parse` to `FromMeta`.
///
/// This cannot be a blanket impl, due to the `syn::Lit` family's need to handle non-string values.
@ -291,9 +366,6 @@ macro_rules! from_syn_parse {
}
from_syn_parse!(syn::Ident);
from_syn_parse!(syn::Expr);
from_syn_parse!(syn::ExprArray);
from_syn_parse!(syn::ExprPath);
from_syn_parse!(syn::Path);
from_syn_parse!(syn::Type);
from_syn_parse!(syn::TypeArray);
@ -318,11 +390,9 @@ macro_rules! from_numeric_array {
($ty:ident) => {
/// Parsing an unsigned integer array, i.e. `example = "[1, 2, 3, 4]"`.
impl FromMeta for Vec<$ty> {
fn from_value(value: &Lit) -> Result<Self> {
let expr_array = syn::ExprArray::from_value(value)?;
// To meet rust <1.36 borrow checker rules on expr_array.elems
let v =
expr_array
fn from_expr(expr: &syn::Expr) -> Result<Self> {
if let syn::Expr::Array(expr_array) = expr {
let v = expr_array
.elems
.iter()
.map(|expr| match expr {
@ -331,7 +401,17 @@ macro_rules! from_numeric_array {
.with_span(expr)),
})
.collect::<Result<Vec<$ty>>>();
v
v
} else if let syn::Expr::Lit(expr_lit) = expr {
Self::from_value(&expr_lit.lit)
} else {
Err(Error::unexpected_expr_type(expr))
}
}
fn from_value(value: &Lit) -> Result<Self> {
let expr_array = syn::ExprArray::from_value(value)?;
Self::from_expr(&syn::Expr::Array(expr_array))
}
}
};
@ -519,7 +599,7 @@ impl KeyFromPath for syn::Ident {
macro_rules! hash_map {
($key:ty) => {
impl<V: FromMeta, S: BuildHasher + Default> FromMeta for HashMap<$key, V, S> {
fn from_list(nested: &[syn::NestedMeta]) -> Result<Self> {
fn from_list(nested: &[NestedMeta]) -> Result<Self> {
// Convert the nested meta items into a sequence of (path, value result) result tuples.
// An outer Err means no (key, value) structured could be found, while an Err in the
// second position of the tuple means that value was rejected by FromMeta.
@ -530,14 +610,14 @@ macro_rules! hash_map {
.iter()
.map(|item| -> Result<(&syn::Path, Result<V>)> {
match *item {
syn::NestedMeta::Meta(ref inner) => {
NestedMeta::Meta(ref inner) => {
let path = inner.path();
Ok((
path,
FromMeta::from_meta(inner).map_err(|e| e.at_path(&path)),
))
}
syn::NestedMeta::Lit(_) => Err(Error::unsupported_format("literal")),
NestedMeta::Lit(_) => Err(Error::unsupported_format("expression")),
}
});
@ -613,9 +693,10 @@ mod tests {
/// parse a string as a syn::Meta instance.
fn pm(tokens: TokenStream) -> ::std::result::Result<syn::Meta, String> {
let attribute: syn::Attribute = parse_quote!(#[#tokens]);
attribute.parse_meta().map_err(|_| "Unable to parse".into())
Ok(attribute.meta)
}
#[track_caller]
fn fm<T: FromMeta>(tokens: TokenStream) -> T {
FromMeta::from_meta(&pm(tokens).expect("Tests should pass well-formed input"))
.expect("Tests should pass valid input")
@ -829,10 +910,7 @@ mod tests {
#[test]
fn test_number_array() {
assert_eq!(
fm::<Vec<u8>>(quote!(ignore = "[16, 0xff]")),
vec![0x10, 0xff]
);
assert_eq!(fm::<Vec<u8>>(quote!(ignore = [16, 0xff])), vec![0x10, 0xff]);
assert_eq!(
fm::<Vec<u16>>(quote!(ignore = "[32, 0xffff]")),
vec![0x20, 0xffff]

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

@ -166,7 +166,7 @@ impl<'a> From<&'a Core> for codegen::TraitImpl<'a> {
.map_enum_variants(|variant| variant.as_codegen_variant(&v.ident)),
default: v.as_codegen_default(),
post_transform: v.post_transform.as_ref(),
bound: v.bound.as_ref().map(|i| i.as_slice()),
bound: v.bound.as_deref(),
allow_unknown_fields: v.allow_unknown_fields.unwrap_or_default(),
}
}

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

@ -1,5 +1,4 @@
use syn::NestedMeta;
use crate::ast::NestedMeta;
use crate::util::PathList;
use crate::{FromMeta, Result};

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

@ -52,13 +52,7 @@ impl ParseData for FdiOptions {
}
fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
match field
.ident
.as_ref()
.map(|v| v.to_string())
.as_ref()
.map(|v| v.as_str())
{
match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
Some("vis") => {
self.vis = field.ident.clone();
Ok(())

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

@ -37,13 +37,7 @@ impl ParseData for FromFieldOptions {
}
fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
match field
.ident
.as_ref()
.map(|v| v.to_string())
.as_ref()
.map(|v| v.as_str())
{
match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
Some("vis") => {
self.vis = field.ident.clone();
Ok(())

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

@ -37,13 +37,7 @@ impl ParseData for FromTypeParamOptions {
}
fn parse_field(&mut self, field: &syn::Field) -> Result<()> {
match field
.ident
.as_ref()
.map(|v| v.to_string())
.as_ref()
.map(|v| v.as_str())
{
match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
Some("bounds") => {
self.bounds = field.ident.clone();
Ok(())

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

@ -58,13 +58,7 @@ impl ParseAttribute for FromVariantOptions {
impl ParseData for FromVariantOptions {
fn parse_field(&mut self, field: &Field) -> Result<()> {
match field
.ident
.as_ref()
.map(|v| v.to_string())
.as_ref()
.map(|v| v.as_str())
{
match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
Some("discriminant") => {
self.discriminant = field.ident.clone();
Ok(())

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

@ -1,6 +1,7 @@
use proc_macro2::Span;
use syn::{parse_quote, spanned::Spanned};
use crate::ast::NestedMeta;
use crate::{Error, FromMeta, Result};
mod core;
@ -50,7 +51,7 @@ impl FromMeta for DefaultExpression {
match item {
syn::Meta::Path(_) => Ok(DefaultExpression::Trait { span: item.span() }),
syn::Meta::List(nm) => Err(Error::unsupported_format("list").with_span(nm)),
syn::Meta::NameValue(nv) => Self::from_value(&nv.lit),
syn::Meta::NameValue(nv) => Self::from_expr(&nv.value),
}
}
@ -66,7 +67,7 @@ pub trait ParseAttribute: Sized {
fn parse_attributes(mut self, attrs: &[syn::Attribute]) -> Result<Self> {
let mut errors = Error::accumulator();
for attr in attrs {
if attr.path == parse_quote!(darling) {
if attr.meta.path() == &parse_quote!(darling) {
errors.handle(parse_attr(attr, &mut self));
}
}
@ -80,10 +81,10 @@ pub trait ParseAttribute: Sized {
fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Result<()> {
let mut errors = Error::accumulator();
match attr.parse_meta().ok() {
Some(syn::Meta::List(data)) => {
for item in data.nested {
if let syn::NestedMeta::Meta(ref mi) = item {
match &attr.meta {
syn::Meta::List(data) => {
for item in NestedMeta::parse_meta_list(data.tokens.clone())? {
if let NestedMeta::Meta(ref mi) = item {
errors.handle(target.parse_nested(mi));
} else {
panic!("Wasn't able to parse: `{:?}`", item);
@ -92,8 +93,7 @@ fn parse_attr<T: ParseAttribute>(attr: &syn::Attribute, target: &mut T) -> Resul
errors.finish()
}
Some(ref item) => panic!("Wasn't able to parse: `{:?}`", item),
None => panic!("Unable to parse {:?}", attr),
item => panic!("Wasn't able to parse: `{:?}`", item),
}
}

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

@ -66,13 +66,7 @@ impl ParseAttribute for OuterFrom {
impl ParseData for OuterFrom {
fn parse_field(&mut self, field: &Field) -> Result<()> {
match field
.ident
.as_ref()
.map(|v| v.to_string())
.as_ref()
.map(|v| v.as_str())
{
match field.ident.as_ref().map(|v| v.to_string()).as_deref() {
Some("ident") => {
self.ident = field.ident.clone();
Ok(())

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

@ -3,8 +3,9 @@
use proc_macro2::TokenStream;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{parse_quote, Meta, NestedMeta};
use syn::{parse_quote, Meta};
use crate::ast::NestedMeta;
use crate::{Error, FromMeta, Result};
/// Receiver struct for shape validation. Shape validation allows a deriving type
@ -225,7 +226,7 @@ mod tests {
/// parse a string as a syn::Meta instance.
fn pm(tokens: TokenStream) -> ::std::result::Result<syn::Meta, String> {
let attribute: syn::Attribute = parse_quote!(#[#tokens]);
attribute.parse_meta().map_err(|_| "Unable to parse".into())
Ok(attribute.meta)
}
fn fm<T: FromMeta>(tokens: TokenStream) -> T {

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

@ -112,20 +112,20 @@ impl UsesLifetimes for Lifetime {
}
uses_lifetimes!(syn::AngleBracketedGenericArguments, args);
uses_lifetimes!(syn::AssocType, ty);
uses_lifetimes!(syn::BareFnArg, ty);
uses_lifetimes!(syn::Binding, ty);
uses_lifetimes!(syn::BoundLifetimes, lifetimes);
uses_lifetimes!(syn::ConstParam, ty);
uses_lifetimes!(syn::Constraint, bounds);
uses_lifetimes!(syn::DataEnum, variants);
uses_lifetimes!(syn::DataStruct, fields);
uses_lifetimes!(syn::DataUnion, fields);
uses_lifetimes!(syn::Field, ty);
uses_lifetimes!(syn::FieldsNamed, named);
uses_lifetimes!(syn::LifetimeDef, lifetime, bounds);
uses_lifetimes!(syn::LifetimeParam, lifetime, bounds);
uses_lifetimes!(syn::ParenthesizedGenericArguments, inputs, output);
uses_lifetimes!(syn::Path, segments);
uses_lifetimes!(syn::PathSegment, arguments);
uses_lifetimes!(syn::PredicateEq, lhs_ty, rhs_ty);
uses_lifetimes!(syn::PredicateLifetime, lifetime, bounds);
uses_lifetimes!(syn::PredicateType, lifetimes, bounded_ty, bounds);
uses_lifetimes!(syn::QSelf, ty);
@ -134,6 +134,7 @@ uses_lifetimes!(syn::TypeArray, elem);
uses_lifetimes!(syn::TypeBareFn, inputs, output);
uses_lifetimes!(syn::TypeGroup, elem);
uses_lifetimes!(syn::TypeImplTrait, bounds);
uses_lifetimes!(syn::TypeParam, bounds);
uses_lifetimes!(syn::TypeParen, elem);
uses_lifetimes!(syn::TypePtr, elem);
uses_lifetimes!(syn::TypeReference, lifetime, elem);
@ -245,7 +246,9 @@ impl UsesLifetimes for syn::WherePredicate {
match *self {
syn::WherePredicate::Type(ref v) => v.uses_lifetimes(options, lifetimes),
syn::WherePredicate::Lifetime(ref v) => v.uses_lifetimes(options, lifetimes),
syn::WherePredicate::Eq(ref v) => v.uses_lifetimes(options, lifetimes),
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::WherePredicate: {:?}", self),
}
}
}
@ -258,10 +261,29 @@ impl UsesLifetimes for syn::GenericArgument {
) -> LifetimeRefSet<'a> {
match *self {
syn::GenericArgument::Type(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericArgument::Binding(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericArgument::AssocType(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericArgument::Lifetime(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericArgument::Constraint(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericArgument::Const(_) => Default::default(),
syn::GenericArgument::AssocConst(_) | syn::GenericArgument::Const(_) => {
Default::default()
}
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::GenericArgument: {:?}", self),
}
}
}
impl UsesLifetimes for syn::GenericParam {
fn uses_lifetimes<'a>(
&self,
options: &Options,
lifetimes: &'a LifetimeSet,
) -> LifetimeRefSet<'a> {
match *self {
syn::GenericParam::Lifetime(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericParam::Type(ref v) => v.uses_lifetimes(options, lifetimes),
syn::GenericParam::Const(ref v) => v.uses_lifetimes(options, lifetimes),
}
}
}
@ -275,6 +297,9 @@ impl UsesLifetimes for syn::TypeParamBound {
match *self {
syn::TypeParamBound::Trait(ref v) => v.uses_lifetimes(options, lifetimes),
syn::TypeParamBound::Lifetime(ref v) => v.uses_lifetimes(options, lifetimes),
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::TypeParamBound: {:?}", self),
}
}
}
@ -282,8 +307,7 @@ impl UsesLifetimes for syn::TypeParamBound {
#[cfg(test)]
mod tests {
use proc_macro2::Span;
use syn::parse_quote;
use syn::DeriveInput;
use syn::{parse_quote, DeriveInput};
use super::UsesLifetimes;
use crate::usage::GenericsExt;

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

@ -87,8 +87,8 @@ impl<T: UsesTypeParams, U> UsesTypeParams for Punctuated<T, U> {
}
uses_type_params!(syn::AngleBracketedGenericArguments, args);
uses_type_params!(syn::AssocType, ty);
uses_type_params!(syn::BareFnArg, ty);
uses_type_params!(syn::Binding, ty);
uses_type_params!(syn::Constraint, bounds);
uses_type_params!(syn::DataEnum, variants);
uses_type_params!(syn::DataStruct, fields);
@ -96,7 +96,6 @@ uses_type_params!(syn::DataUnion, fields);
uses_type_params!(syn::Field, ty);
uses_type_params!(syn::FieldsNamed, named);
uses_type_params!(syn::ParenthesizedGenericArguments, inputs, output);
uses_type_params!(syn::PredicateEq, lhs_ty, rhs_ty);
uses_type_params!(syn::PredicateType, bounded_ty, bounds);
uses_type_params!(syn::QSelf, ty);
uses_type_params!(syn::TraitBound, path);
@ -217,7 +216,9 @@ impl UsesTypeParams for syn::WherePredicate {
match *self {
syn::WherePredicate::Lifetime(_) => Default::default(),
syn::WherePredicate::Type(ref v) => v.uses_type_params(options, type_set),
syn::WherePredicate::Eq(ref v) => v.uses_type_params(options, type_set),
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::WherePredicate: {:?}", self),
}
}
}
@ -226,11 +227,14 @@ impl UsesTypeParams for syn::GenericArgument {
fn uses_type_params<'a>(&self, options: &Options, type_set: &'a IdentSet) -> IdentRefSet<'a> {
match *self {
syn::GenericArgument::Type(ref v) => v.uses_type_params(options, type_set),
syn::GenericArgument::Binding(ref v) => v.uses_type_params(options, type_set),
syn::GenericArgument::AssocType(ref v) => v.uses_type_params(options, type_set),
syn::GenericArgument::Constraint(ref v) => v.uses_type_params(options, type_set),
syn::GenericArgument::Const(_) | syn::GenericArgument::Lifetime(_) => {
Default::default()
}
syn::GenericArgument::AssocConst(_)
| syn::GenericArgument::Const(_)
| syn::GenericArgument::Lifetime(_) => Default::default(),
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::GenericArgument: {:?}", self),
}
}
}
@ -240,6 +244,9 @@ impl UsesTypeParams for syn::TypeParamBound {
match *self {
syn::TypeParamBound::Trait(ref v) => v.uses_type_params(options, type_set),
syn::TypeParamBound::Lifetime(_) => Default::default(),
// non-exhaustive enum
// TODO: replace panic with failible function
_ => panic!("Unknown syn::TypeParamBound: {:?}", self),
}
}
}
@ -323,7 +330,7 @@ mod tests {
#[test]
fn box_fn_output() {
let input: DeriveInput = parse_quote! { struct Foo<T>(Box<Fn() -> T>); };
let input: DeriveInput = parse_quote! { struct Foo<T>(Box<dyn Fn() -> T>); };
let generics = ident_set(vec!["T"]);
let matches = input.data.uses_type_params(&BoundImpl.into(), &generics);
assert_eq!(matches.len(), 1);
@ -332,7 +339,7 @@ mod tests {
#[test]
fn box_fn_input() {
let input: DeriveInput = parse_quote! { struct Foo<T>(Box<Fn(&T) -> ()>); };
let input: DeriveInput = parse_quote! { struct Foo<T>(Box<dyn Fn(&T) -> ()>); };
let generics = ident_set(vec!["T"]);
let matches = input.data.uses_type_params(&BoundImpl.into(), &generics);
assert_eq!(matches.len(), 1);

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

@ -77,12 +77,6 @@ impl FromMeta for Flag {
}
}
impl Spanned for Flag {
fn span(&self) -> Span {
self.0.unwrap_or_else(Span::call_site)
}
}
impl From<Flag> for bool {
fn from(flag: Flag) -> Self {
flag.is_present()

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

@ -1,7 +1,8 @@
use std::fmt;
use syn::{Lit, NestedMeta};
use syn::Lit;
use crate::ast::NestedMeta;
use crate::{FromMeta, Result};
use self::Override::*;

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

@ -1,25 +1,34 @@
use crate::{util::SpannedValue, Error, Result};
use crate::{Error, Result};
use std::fmt;
use syn::{punctuated::Pair, spanned::Spanned, token, Attribute, Meta, MetaList, Path};
use syn::punctuated::Pair;
use syn::spanned::Spanned;
use syn::{token, Attribute, Meta, MetaList, Path};
/// Try to parse an attribute into a meta list. Path-type meta values are accepted and returned
/// as empty lists with their passed-in path. Name-value meta values and non-meta attributes
/// will cause errors to be returned.
pub fn parse_attribute_to_meta_list(attr: &Attribute) -> Result<MetaList> {
match attr.parse_meta() {
Ok(Meta::List(list)) => Ok(list),
Ok(Meta::NameValue(nv)) => Err(Error::custom(format!(
match &attr.meta {
Meta::List(list) => Ok(list.clone()),
Meta::NameValue(nv) => Err(Error::custom(format!(
"Name-value arguments are not supported. Use #[{}(...)]",
DisplayPath(&nv.path)
))
.with_span(&nv)),
Ok(Meta::Path(path)) => Ok(MetaList {
path,
paren_token: token::Paren(attr.span()),
nested: Default::default(),
Meta::Path(path) => Ok(MetaList {
path: path.clone(),
delimiter: syn::MacroDelimiter::Paren(token::Paren {
span: {
let mut group = proc_macro2::Group::new(
proc_macro2::Delimiter::None,
proc_macro2::TokenStream::new(),
);
group.set_span(attr.span());
group.delim_span()
},
}),
tokens: Default::default(),
}),
Err(e) => Err(Error::custom(format!("Unable to parse attribute: {}", e))
.with_span(&SpannedValue::new((), e.span()))),
}
}
@ -45,19 +54,23 @@ impl fmt::Display for DisplayPath<'_> {
#[cfg(test)]
mod tests {
use super::parse_attribute_to_meta_list;
use syn::{parse_quote, spanned::Spanned, Ident};
use crate::ast::NestedMeta;
use syn::spanned::Spanned;
use syn::{parse_quote, Ident};
#[test]
fn parse_list() {
let meta = parse_attribute_to_meta_list(&parse_quote!(#[bar(baz = 4)])).unwrap();
assert_eq!(meta.nested.len(), 1);
let nested_meta = NestedMeta::parse_meta_list(meta.tokens).unwrap();
assert_eq!(nested_meta.len(), 1);
}
#[test]
fn parse_path_returns_empty_list() {
let meta = parse_attribute_to_meta_list(&parse_quote!(#[bar])).unwrap();
let nested_meta = NestedMeta::parse_meta_list(meta.tokens).unwrap();
assert!(meta.path.is_ident(&Ident::new("bar", meta.path.span())));
assert!(meta.nested.is_empty());
assert!(nested_meta.is_empty());
}
#[test]

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

@ -1,7 +1,8 @@
use std::ops::Deref;
use syn::{Meta, NestedMeta, Path};
use syn::{Meta, Path};
use crate::ast::NestedMeta;
use crate::{Error, FromMeta, Result};
use super::path_to_string;
@ -72,7 +73,7 @@ mod tests {
/// parse a string as a syn::Meta instance.
fn pm(tokens: TokenStream) -> ::std::result::Result<Meta, String> {
let attribute: Attribute = parse_quote!(#[#tokens]);
attribute.parse_meta().map_err(|_| "Unable to parse".into())
Ok(attribute.meta)
}
fn fm<T: FromMeta>(tokens: TokenStream) -> T {

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

@ -67,12 +67,6 @@ impl<T> AsRef<T> for SpannedValue<T> {
}
}
impl<T> Spanned for SpannedValue<T> {
fn span(&self) -> Span {
self.span
}
}
macro_rules! spanned {
($trayt:ident, $method:ident, $syn:path) => {
impl<T: $trayt> $trayt for SpannedValue<T> {
@ -95,10 +89,10 @@ impl<T: FromMeta> FromMeta for SpannedValue<T> {
syn::Meta::Path(path) => path.span(),
// Example: `#[darling(attributes(Value))]` as a SpannedValue<Vec<String>>
// should have the span pointing to the list contents.
syn::Meta::List(list) => list.nested.span(),
syn::Meta::List(list) => list.tokens.span(),
// Example: `#[darling(skip = true)]` as SpannedValue<bool>
// should have the span pointing to the word `true`.
syn::Meta::NameValue(nv) => nv.lit.span(),
syn::Meta::NameValue(nv) => nv.value.span(),
};
Ok(Self::new(value, span))

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

@ -1 +1 @@
{"files":{"Cargo.toml":"f9ca47216222c1dc994ecdd2e10117060f025c1306bc93b93f5b3683c50033cd","LICENSE":"8ea93490d74a5a1b1af3ff71d786271b3f1e5f0bea79ac16e02ec533cef040d6","src/lib.rs":"1dbd1ed31a7db5ff7995bd1dd494e962645e6ff62b0f88807fe1b6025523f187"},"package":"b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"}
{"files":{"Cargo.toml":"9df103094522de168893c7805273fe0de11ab18405db65d669af71aa6e810955","LICENSE":"8ea93490d74a5a1b1af3ff71d786271b3f1e5f0bea79ac16e02ec533cef040d6","src/lib.rs":"728be3bb12c9cdaaf0520bce87e489a0820e436c78fa3627e238fc1acc11dd7f"},"package":"29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a"}

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

@ -12,7 +12,7 @@
[package]
edition = "2018"
name = "darling_macro"
version = "0.14.3"
version = "0.20.1"
authors = ["Ted Driggs <ted.driggs@outlook.com>"]
description = """
Internal support for a proc-macro library for reading attributes into structs when
@ -25,10 +25,10 @@ repository = "https://github.com/TedDriggs/darling"
proc-macro = true
[dependencies.darling_core]
version = "=0.14.3"
version = "=0.20.1"
[dependencies.quote]
version = "1.0.18"
[dependencies.syn]
version = "1.0.91"
version = "2.0.15"

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

@ -1,6 +1,3 @@
// This is needed for 1.31.0 to keep compiling
extern crate proc_macro;
use darling_core::{derive, Error};
use proc_macro::TokenStream;
use syn::parse_macro_input;

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

@ -1 +1 @@
{"files":{"Cargo.toml":"d0d1787c790db1c5196cb6cc3ce3ed9b670f24d8e10532df4ce1af08b4f446f5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"79b4502d93c23afe2765054a80d03716d4934eb260cdfbe8c401898df3aa5a8f","README.md":"b4272f04bf647cd6c5d395772a63fa44230df914347ce71f0d2ad7371c7a0bdd","src/lib.rs":"5f0d4ca19512bd146c4d1c1e287385860c7fa4c8906b7eb92843a442c3efea0a","src/repr.rs":"3ec64837ced263c1e2ae3a548b4bed553c85286f6d2b89b4b7dd2358c21d6fcb","tests/compile-fail/variants.rs":"b4b4d8d2a1ea37afb1c478c81a3157d9ea7ab4a2cbf00b7b71386c37f99f2b0b","tests/compile-fail/variants.stderr":"f0d4d9ebcf9cccea04a0796ca2f4a2a81ebaa235f78edf30aeb30a3f232ec1f0","tests/compile-pass/no_imports.rs":"6fa96d43c3970e25dd1e216820dd79f22f5bfe416ce7d6a6df86781797279297","tests/compile-pass/no_std.rs":"e8a402ae12562e6eab4ac531c084278a9dda4ac9b4e64b7a37bb87ce890738e7","tests/ops.rs":"7a00df1ca4a502292f926529d8979e6e3476f48931487088ca50fc869d00e8ff","tests/repr.rs":"a1b792a3b6f71db62b7b26b9b880783b4fd6c905c170c35a0e4b90ccc2a701c9","tests/serde.rs":"8dd9717ee36b26c4b762a258693030ae27e3990625e513694ff3d68af0a131fd","tests/trybuild.rs":"22e03e02452e47976668c3d4ed54322e4d19a95bd1f72647f5d5792b80e8d0f1"},"package":"19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753"}
{"files":{"Cargo.toml":"f173fbd9ad98e0eb5077ec8d2fa39321e3c634500c7b1c5f1e7c792e47a590c8","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7405fdff2ff8682a5384da664436b9b2aca47557572513f5b27686a5347f9b8e","README.md":"d909f3ef0b7937f6d6d0a8171e056671f717561f2679c6da43254a528711d285","src/lib.rs":"3bb0f56eb0e15acc4f99db31f17567c0479d3b364743f94d132d7d4c6c07db5c","src/macros.rs":"01d43156f78cb32caee75263cf613d5018a30fbaafdcd403dd0abb15aa28abca","src/repr/array.rs":"8c082259fcbd0842ea52844b03c88b98f39ed59a381c83b278e574357b972d58","src/repr/mod.rs":"88fa5138818c5246539814da6bd1b27c790abf64f003af4ce05c83f3e8c4e5d2","src/repr/primitive.rs":"1d6e97c7990e7028f6860ac2acf080f247c894d4c050818d36a55f017edaa956","src/set.rs":"7546fd252fbd2b9d1eb6f86b6c0cfcdd69573528335cbcdfe8006de5236ed5bd","src/traits.rs":"533a2e62c09e956538013bc9a852d0ae336d4bf0a0f8f0494fbf5743bbd27da9","tests/compile-fail-serde/deprecation.rs":"fa6be473bffb4f37ad9407f8712a98c30d32ced00f52749a21d127167037a58a","tests/compile-fail-serde/deprecation.stderr":"7639d3599c3bbbbfe7763dac33307037ba8fa7914f2e1c3502271dad4a0663a7","tests/compile-fail/explicit_repr.rs":"8d3afa63274224c8f526df3a1b5a0435de51343fc4e7b5cbf717d15c38f7f5c5","tests/compile-fail/explicit_repr.stderr":"beaf53132cafb18c58ad8f66ff276bb2b51e34bc9c6880dbe5cdb125422c6f2f","tests/compile-fail/syntax.rs":"eab09b5f611c60e086299a5bfb3aa7e6622b736524e4480a5b7c55a6efe2f34f","tests/compile-fail/syntax.stderr":"9892d3eed892a9dadb7abf308257d5b38bf67902430b7cb07aa0c2c61bfba823","tests/compile-fail/variants.rs":"2e9d69cce5f53addda5352588168882cc47833f765e8db631ba1fd9162271e67","tests/compile-fail/variants.stderr":"47f7a545c8bcaea3b8f31a17395abd98c4b4f1799e0d9ad9389e973e26be13e5","tests/compile-pass/no_imports.rs":"6fa96d43c3970e25dd1e216820dd79f22f5bfe416ce7d6a6df86781797279297","tests/compile-pass/no_std.rs":"e8a402ae12562e6eab4ac531c084278a9dda4ac9b4e64b7a37bb87ce890738e7","tests/conversions.rs":"06683f3f89bb580c1feb9e2c3482b5d9df5e18d1f5d0c2fe1abf4ebfcba5d12e","tests/ops.rs":"ce2b5f7979c72c3f2952a2e4cd4c94cc1895100c594ff19c97edd09e631c6cdf","tests/repr.rs":"a1b792a3b6f71db62b7b26b9b880783b4fd6c905c170c35a0e4b90ccc2a701c9","tests/serde.rs":"f8ea3b9a5f944c48a35a2ad68c7b61a7e1ef4ad60dd3f5523feec3a51edfdba5","tests/trybuild.rs":"5bdb2e3777c1162ffb3b00475130c5032c7d34a2c4f822b898bc79eef722ba97"},"package":"e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb"}

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

@ -10,9 +10,9 @@
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
edition = "2021"
name = "enumset"
version = "1.0.12"
version = "1.1.2"
authors = ["Alissa Rao <lymia@lymiahugs.com>"]
description = "A library for creating compact sets of enums."
documentation = "https://docs.rs/enumset/"
@ -24,9 +24,17 @@ keywords = [
categories = ["data-structures"]
license = "MIT/Apache-2.0"
repository = "https://github.com/Lymia/enumset"
resolver = "1"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
]
[dependencies.enumset_derive]
version = "0.6.1"
version = "0.8.0"
[dependencies.serde2]
version = "1"

2
third_party/rust/enumset/LICENSE-MIT поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
Copyright (c) 2017-2020 Alissa Rao <lymiahugs@gmail.com>
Copyright (c) 2017-2023 Alissa Rao <lymiahugs@gmail.com>
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

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

@ -2,11 +2,12 @@
[![Build Status](https://github.com/Lymia/enumset/actions/workflows/test.yml/badge.svg)](https://github.com/Lymia/enumset/actions/workflows/test.yml)
[![Latest Version](https://img.shields.io/crates/v/enumset.svg)](https://crates.io/crates/enumset)
![Requires rustc 1.36+](https://img.shields.io/badge/rustc-1.36+-red.svg)
![Requires rustc 1.56+](https://img.shields.io/badge/rustc-1.56+-red.svg)
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/enumset)
A library for defining enums that can be used in compact bit sets.
It supports enums up to 128 variants, and has a macro to use these sets in constants.
A library for defining enums that can be used in compact bit sets. It supports
`serde` and `#[no_std]` environments, and has basic support for using EnumSets
in constants.
See [the documentation](https://docs.rs/enumset) for more information.

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

@ -1,12 +1,16 @@
#![no_std]
#![forbid(missing_docs)]
// The safety requirement is "use the procedural derive".
#![allow(clippy::missing_safety_doc)]
#![deny(missing_docs)]
#![allow(clippy::missing_safety_doc)] // The safety requirement is "use the procedural derive".
#![allow(clippy::needless_range_loop)] // range loop style is clearer in most places in enumset
#![cfg_attr(docsrs, feature(doc_cfg))]
//! A library for defining enums that can be used in compact bit sets. It supports enums up to 128
//! variants, and has a macro to use these sets in constants.
//! A library for defining enums that can be used in compact bit sets. It supports arbitrarily
//! large enums, and has very basic support for using them in constants.
//!
//! For serde support, enable the `serde` feature.
//! The following feature flags may be used for this crate:
//!
//! * `serde` enables serialization support for [`EnumSet`].
//! * `alloc` enables functions that require allocation.
//!
//! # Defining enums for use with EnumSet
//!
@ -78,64 +82,32 @@
//! assert_eq!(set, Enum::A | Enum::E | Enum::G);
//! ```
use core::cmp::Ordering;
use core::fmt;
use core::fmt::{Debug, Formatter};
use core::hash::{Hash, Hasher};
use core::iter::{FromIterator, Sum};
use core::ops::*;
#[cfg(feature = "alloc")]
extern crate alloc;
#[doc(hidden)]
/// Everything in this module is internal API and may change at any time.
pub mod __internal {
use super::*;
/// A reexport of core to allow our macros to be generic to std vs core.
pub use ::core as core_export;
/// A reexport of serde so there is no requirement to depend on serde.
#[cfg(feature = "serde")]
pub use serde2 as serde;
/// The actual members of EnumSetType. Put here to avoid polluting global namespaces.
pub unsafe trait EnumSetTypePrivate {
/// The underlying type used to store the bitset.
type Repr: EnumSetTypeRepr;
/// A mask of bits that are valid in the bitset.
const ALL_BITS: Self::Repr;
/// Converts an enum of this type into its bit position.
fn enum_into_u32(self) -> u32;
/// Converts a bit position into an enum value.
unsafe fn enum_from_u32(val: u32) -> Self;
/// Serializes the `EnumSet`.
///
/// This and `deserialize` are part of the `EnumSetType` trait so the procedural derive
/// can control how `EnumSet` is serialized.
#[cfg(feature = "serde")]
fn serialize<S: serde::Serializer>(set: EnumSet<Self>, ser: S) -> Result<S::Ok, S::Error>
where Self: EnumSetType;
/// Deserializes the `EnumSet`.
#[cfg(feature = "serde")]
fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<EnumSet<Self>, D::Error>
where Self: EnumSetType;
}
}
#[cfg(feature = "serde")]
use crate::__internal::serde;
use crate::__internal::EnumSetTypePrivate;
#[cfg(feature = "serde")]
use crate::serde::{Deserialize, Serialize};
mod macros;
mod repr;
use crate::repr::EnumSetTypeRepr;
mod set;
mod traits;
pub use crate::macros::__internal;
pub use crate::set::{EnumSet, EnumSetIter};
pub use crate::traits::{EnumSetType, EnumSetTypeWithRepr};
/// The procedural macro used to derive [`EnumSetType`], and allow enums to be used with
/// [`EnumSet`].
///
/// It may be used with any enum with no data fields, at most 127 variants, and no variant
/// discriminators larger than 127.
/// # Limitations
///
/// Currently, the following limitations apply to what kinds of enums this macro may be used with:
///
/// * The enum must have no data fields in any variant.
/// * Variant discriminators must be zero or positive.
/// * No variant discriminator may be larger than `0xFFFFFFBF`. This is chosen to limit problems
/// involving overflow and similar edge cases.
/// * Variant discriminators must be defined with integer literals. Expressions like `V = 1 + 1`
/// are not currently supported.
///
/// # Additional Impls
///
@ -173,15 +145,16 @@ use crate::repr::EnumSetTypeRepr;
/// “FFI, Safety and `repr`”][EnumSet#ffi-safety-and-repr]. Allowed types are `u8`, `u16`, `u32`,
/// `u64` and `u128`. If this is not used, then the derive macro will choose a type to best fit
/// the enum, but there are no guarantees about which type will be chosen.
/// * `#[enumset(repr = "array")]` forces the `EnumSet` of this type to be backed with an array,
/// even if all the variants could fit into a primitive numeric type.
///
/// When the `serde` feature is used, the following features may also be specified. These options
/// may be used (with no effect) when building without the feature enabled:
///
/// * `#[enumset(serialize_repr = "u8")]` may be used to specify the integer type used to serialize
/// the underlying bitset. Any type allowed in the `repr` option may be used in this option.
/// * `#[enumset(serialize_as_list)]` may be used to serialize the bitset as a list of enum
/// variants instead of an integer. This requires [`Deserialize`] and [`Serialize`] be
/// implemented on the enum.
/// * `#[enumset(serialize_repr = "…")]` may be used to override the way the `EnumSet` is
/// serialized. Valid options are `u8`, `u16`, `u32`, `u64`, `list`, `map` and `array`. For more
/// information, see the ["Serialization" section of the `EnumSet` documentation]
/// (EnumSet#serialization).
/// * `#[enumset(serialize_deny_unknown)]` causes the generated deserializer to return an error
/// for unknown bits instead of silently ignoring them.
///
@ -217,755 +190,10 @@ use crate::repr::EnumSetTypeRepr;
/// A, B, C, D, E, F, G,
/// }
/// ```
///
/// [`Sub`]: core::ops::Sub
/// [`BitAnd`]: core::ops::BitAnd
/// [`BitOr`]: core::ops::BitOr
/// [`BitXor`]: core::ops::BitXor
/// [`Not`]: core::ops::Not
pub use enumset_derive::EnumSetType;
/// The trait used to define enum types that may be used with [`EnumSet`].
///
/// This trait must be impelmented using `#[derive(EnumSetType)]`, is not public API, and its
/// internal structure may change at any time with no warning.
///
/// For full documentation on the procedural derive and its options, see
/// [`#[derive(EnumSetType)]`](./derive.EnumSetType.html).
pub unsafe trait EnumSetType: Copy + Eq + EnumSetTypePrivate {}
/// An [`EnumSetType`] for which [`EnumSet`]s have a guaranteed in-memory representation.
///
/// An implementation of this trait is generated by using
/// [`#[derive(EnumSetType)]`](./derive.EnumSetType.html) with the annotation
/// `#[enumset(repr = "…")]`, where `…` is `u8`, `u16`, `u32`, `u64` or `u128`.
///
/// For any type `T` that implements this trait, the in-memory representation of `EnumSet<T>`
/// is guaranteed to be `Repr`. This guarantee is useful for FFI. See [the `EnumSet` documentation
/// under “FFI, Safety and `repr`”][EnumSet#ffi-safety-and-repr] for an example.
pub unsafe trait EnumSetTypeWithRepr:
EnumSetType + EnumSetTypePrivate<Repr = <Self as EnumSetTypeWithRepr>::Repr>
{
/// The guaranteed representation.
type Repr: EnumSetTypeRepr;
}
/// An efficient set type for enums.
///
/// It is implemented using a bitset stored using the smallest integer that can fit all bits
/// in the underlying enum. In general, an enum variant with a discriminator of `n` is stored in
/// the nth least significant bit (corresponding with a mask of, e.g. `1 << enum as u32`).
///
/// # Numeric representation
///
/// `EnumSet` is internally implemented using integer types, and as such can be easily converted
/// from and to numbers.
///
/// Each bit of the underlying integer corresponds to at most one particular enum variant. If the
/// corresponding bit for a variant is set, it present in the set. Bits that do not correspond to
/// any variant are always unset.
///
/// By default, each enum variant is stored in a bit corresponding to its discriminator. An enum
/// variant with a discriminator of `n` is stored in the `n + 1`th least significant bit
/// (corresponding to a mask of e.g. `1 << enum as u32`).
///
/// # Serialization
///
/// When the `serde` feature is enabled, `EnumSet`s can be serialized and deserialized using
/// the `serde` crate. The exact serialization format can be controlled with additional attributes
/// on the enum type. These attributes are valid regardless of whether the `serde` feature
/// is enabled.
///
/// By default, `EnumSet`s serialize by directly writing out the underlying bitset as an integer
/// of the smallest type that can fit in the underlying enum. You can add a
/// `#[enumset(serialize_repr = "u8")]` attribute to your enum to control the integer type used
/// for serialization. This can be important for avoiding unintentional breaking changes when
/// `EnumSet`s are serialized with formats like `bincode`.
///
/// By default, unknown bits are ignored and silently removed from the bitset. To override thris
/// behavior, you can add a `#[enumset(serialize_deny_unknown)]` attribute. This will cause
/// deserialization to fail if an invalid bit is set.
///
/// In addition, the `#[enumset(serialize_as_list)]` attribute causes the `EnumSet` to be
/// instead serialized as a list of enum variants. This requires your enum type implement
/// [`Serialize`] and [`Deserialize`]. Note that this is a breaking change.
///
/// # FFI, Safety and `repr`
///
/// If an enum type `T` is annotated with [`#[enumset(repr = "R")]`][derive@EnumSetType#options],
/// then several things happen:
///
/// * `T` will implement <code>[EnumSetTypeWithRepr]&lt;Repr = R&gt;</code> in addition to
/// [`EnumSetType`].
/// * The `EnumSet` methods with `repr` in their name, such as [`as_repr`][EnumSet::as_repr] and
/// [`from_repr`][EnumSet::from_repr], will be available for `EnumSet<T>`.
/// * The in-memory representation of `EnumSet<T>` is guaranteed to be `R`.
///
/// That last guarantee makes it sound to send `EnumSet<T>` across an FFI boundary. For example:
///
/// ```
/// # use enumset::*;
/// #
/// # mod ffi_impl {
/// # // This example “foreign” function is actually written in Rust, but for the sake
/// # // of example, we'll pretend it's written in C.
/// # #[no_mangle]
/// # extern "C" fn some_foreign_function(set: u32) -> u32 {
/// # set & 0b100
/// # }
/// # }
/// #
/// extern "C" {
/// // This function is written in C like:
/// // uint32_t some_foreign_function(uint32_t set) { … }
/// fn some_foreign_function(set: EnumSet<MyEnum>) -> EnumSet<MyEnum>;
/// }
///
/// #[derive(Debug, EnumSetType)]
/// #[enumset(repr = "u32")]
/// enum MyEnum { A, B, C }
///
/// let set: EnumSet<MyEnum> = enum_set!(MyEnum::A | MyEnum::C);
///
/// let new_set: EnumSet<MyEnum> = unsafe { some_foreign_function(set) };
/// assert_eq!(new_set, enum_set!(MyEnum::C));
/// ```
///
/// When an `EnumSet<T>` is received via FFI, all bits that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set to `1`.
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct EnumSet<T: EnumSetType> {
#[doc(hidden)]
/// This is public due to the [`enum_set!`] macro.
/// This is **NOT** public API and may change at any time.
pub __priv_repr: T::Repr,
}
impl<T: EnumSetType> EnumSet<T> {
// Returns all bits valid for the enum
#[inline(always)]
fn all_bits() -> T::Repr {
T::ALL_BITS
}
/// Creates an empty `EnumSet`.
#[inline(always)]
pub fn new() -> Self {
EnumSet { __priv_repr: T::Repr::empty() }
}
/// Returns an `EnumSet` containing a single element.
#[inline(always)]
pub fn only(t: T) -> Self {
let mut set = Self::new();
set.insert(t);
set
}
/// Creates an empty `EnumSet`.
///
/// This is an alias for [`EnumSet::new`].
#[inline(always)]
pub fn empty() -> Self {
Self::new()
}
/// Returns an `EnumSet` containing all valid variants of the enum.
#[inline(always)]
pub fn all() -> Self {
EnumSet { __priv_repr: Self::all_bits() }
}
/// Total number of bits used by this type. Note that the actual amount of space used is
/// rounded up to the next highest integer type (`u8`, `u16`, `u32`, `u64`, or `u128`).
///
/// This is the same as [`EnumSet::variant_count`] except in enums with "sparse" variants.
/// (e.g. `enum Foo { A = 10, B = 20 }`)
#[inline(always)]
pub fn bit_width() -> u32 {
T::Repr::WIDTH - T::ALL_BITS.leading_zeros()
}
/// The number of valid variants that this type can contain.
///
/// This is the same as [`EnumSet::bit_width`] except in enums with "sparse" variants.
/// (e.g. `enum Foo { A = 10, B = 20 }`)
#[inline(always)]
pub fn variant_count() -> u32 {
T::ALL_BITS.count_ones()
}
/// Returns the number of elements in this set.
#[inline(always)]
pub fn len(&self) -> usize {
self.__priv_repr.count_ones() as usize
}
/// Returns `true` if the set contains no elements.
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.__priv_repr.is_empty()
}
/// Removes all elements from the set.
#[inline(always)]
pub fn clear(&mut self) {
self.__priv_repr = T::Repr::empty()
}
/// Returns `true` if `self` has no elements in common with `other`. This is equivalent to
/// checking for an empty intersection.
#[inline(always)]
pub fn is_disjoint(&self, other: Self) -> bool {
(*self & other).is_empty()
}
/// Returns `true` if the set is a superset of another, i.e., `self` contains at least all the
/// values in `other`.
#[inline(always)]
pub fn is_superset(&self, other: Self) -> bool {
(*self & other).__priv_repr == other.__priv_repr
}
/// Returns `true` if the set is a subset of another, i.e., `other` contains at least all
/// the values in `self`.
#[inline(always)]
pub fn is_subset(&self, other: Self) -> bool {
other.is_superset(*self)
}
/// Returns a set containing any elements present in either set.
#[inline(always)]
pub fn union(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr | other.__priv_repr }
}
/// Returns a set containing every element present in both sets.
#[inline(always)]
pub fn intersection(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr & other.__priv_repr }
}
/// Returns a set containing element present in `self` but not in `other`.
#[inline(always)]
pub fn difference(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr.and_not(other.__priv_repr) }
}
/// Returns a set containing every element present in either `self` or `other`, but is not
/// present in both.
#[inline(always)]
pub fn symmetrical_difference(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr ^ other.__priv_repr }
}
/// Returns a set containing all enum variants not in this set.
#[inline(always)]
pub fn complement(&self) -> Self {
EnumSet { __priv_repr: !self.__priv_repr & Self::all_bits() }
}
/// Checks whether this set contains a value.
#[inline(always)]
pub fn contains(&self, value: T) -> bool {
self.__priv_repr.has_bit(value.enum_into_u32())
}
/// Adds a value to this set.
///
/// If the set did not have this value present, `true` is returned.
///
/// If the set did have this value present, `false` is returned.
#[inline(always)]
pub fn insert(&mut self, value: T) -> bool {
let contains = !self.contains(value);
self.__priv_repr.add_bit(value.enum_into_u32());
contains
}
/// Removes a value from this set. Returns whether the value was present in the set.
#[inline(always)]
pub fn remove(&mut self, value: T) -> bool {
let contains = self.contains(value);
self.__priv_repr.remove_bit(value.enum_into_u32());
contains
}
/// Adds all elements in another set to this one.
#[inline(always)]
pub fn insert_all(&mut self, other: Self) {
self.__priv_repr = self.__priv_repr | other.__priv_repr
}
/// Removes all values in another set from this one.
#[inline(always)]
pub fn remove_all(&mut self, other: Self) {
self.__priv_repr = self.__priv_repr.and_not(other.__priv_repr);
}
/// Iterates the contents of the set in order from the least significant bit to the most
/// significant bit.
///
/// Note that iterator invalidation is impossible as the iterator contains a copy of this type,
/// rather than holding a reference to it.
pub fn iter(&self) -> EnumSetIter<T> {
EnumSetIter::new(*self)
}
/// Returns a `T::Repr` representing the elements of this set.
///
/// Unlike the other `as_*` methods, this method is zero-cost and guaranteed not to fail,
/// panic or truncate any bits.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr
where T: EnumSetTypeWithRepr {
self.__priv_repr
}
/// Constructs a bitset from a `T::Repr` without checking for invalid bits.
///
/// Unlike the other `from_*` methods, this method is zero-cost and guaranteed not to fail,
/// panic or truncate any bits, provided the conditions under “Safety” are upheld.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant of
/// `T` must be set to `0`. Behavior is **undefined** if any of these bits are set to `1`.
#[inline(always)]
pub unsafe fn from_repr_unchecked(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self
where T: EnumSetTypeWithRepr {
Self { __priv_repr: bits }
}
/// Constructs a bitset from a `T::Repr`.
///
/// If a bit that doesn't correspond to an enum variant is set, this
/// method will panic.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self
where T: EnumSetTypeWithRepr {
Self::try_from_repr(bits).expect("Bitset contains invalid variants.")
}
/// Attempts to constructs a bitset from a `T::Repr`.
///
/// If a bit that doesn't correspond to an enum variant is set, this
/// method will return `None`.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn try_from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Option<Self>
where T: EnumSetTypeWithRepr {
let mask = Self::all().__priv_repr;
if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
}
}
/// Constructs a bitset from a `T::Repr`, ignoring invalid variants.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self
where T: EnumSetTypeWithRepr {
let mask = Self::all().as_repr();
let bits = bits & mask;
EnumSet { __priv_repr: bits }
}
}
/// Helper macro for generating conversion functions.
macro_rules! conversion_impls {
(
$(for_num!(
$underlying:ty, $underlying_str:expr,
$from_fn:ident $to_fn:ident $from_fn_opt:ident $to_fn_opt:ident,
$from:ident $try_from:ident $from_truncated:ident $from_unchecked:ident,
$to:ident $try_to:ident $to_truncated:ident
);)*
) => {
impl <T : EnumSetType> EnumSet<T> {$(
#[doc = "Returns a `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "` or contains bits that do not correspond to an enum variant, this method \
will panic."]
#[inline(always)]
pub fn $to(&self) -> $underlying {
self.$try_to().expect("Bitset will not fit into this type.")
}
#[doc = "Tries to return a `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "` or contains bits that do not correspond to an enum variant, this method \
will instead return `None`."]
#[inline(always)]
pub fn $try_to(&self) -> Option<$underlying> {
EnumSetTypeRepr::$to_fn_opt(&self.__priv_repr)
}
#[doc = "Returns a truncated `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "`, this method will truncate any bits that don't fit or do not correspond \
to an enum variant."]
#[inline(always)]
pub fn $to_truncated(&self) -> $underlying {
EnumSetTypeRepr::$to_fn(&self.__priv_repr)
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
method will panic."]
#[inline(always)]
pub fn $from(bits: $underlying) -> Self {
Self::$try_from(bits).expect("Bitset contains invalid variants.")
}
#[doc = "Attempts to constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
method will return `None`."]
#[inline(always)]
pub fn $try_from(bits: $underlying) -> Option<Self> {
let bits = T::Repr::$from_fn_opt(bits);
let mask = Self::all().__priv_repr;
bits.and_then(|bits| if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
})
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`, ignoring invalid variants."]
#[inline(always)]
pub fn $from_truncated(bits: $underlying) -> Self {
let mask = Self::all().$to_truncated();
let bits = <T::Repr as EnumSetTypeRepr>::$from_fn(bits & mask);
EnumSet { __priv_repr: bits }
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`, without checking for invalid bits."]
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set
/// to `1`.
#[inline(always)]
pub unsafe fn $from_unchecked(bits: $underlying) -> Self {
EnumSet { __priv_repr: <T::Repr as EnumSetTypeRepr>::$from_fn(bits) }
}
)*}
}
}
conversion_impls! {
for_num!(u8, "u8",
from_u8 to_u8 from_u8_opt to_u8_opt,
from_u8 try_from_u8 from_u8_truncated from_u8_unchecked,
as_u8 try_as_u8 as_u8_truncated);
for_num!(u16, "u16",
from_u16 to_u16 from_u16_opt to_u16_opt,
from_u16 try_from_u16 from_u16_truncated from_u16_unchecked,
as_u16 try_as_u16 as_u16_truncated);
for_num!(u32, "u32",
from_u32 to_u32 from_u32_opt to_u32_opt,
from_u32 try_from_u32 from_u32_truncated from_u32_unchecked,
as_u32 try_as_u32 as_u32_truncated);
for_num!(u64, "u64",
from_u64 to_u64 from_u64_opt to_u64_opt,
from_u64 try_from_u64 from_u64_truncated from_u64_unchecked,
as_u64 try_as_u64 as_u64_truncated);
for_num!(u128, "u128",
from_u128 to_u128 from_u128_opt to_u128_opt,
from_u128 try_from_u128 from_u128_truncated from_u128_unchecked,
as_u128 try_as_u128 as_u128_truncated);
for_num!(usize, "usize",
from_usize to_usize from_usize_opt to_usize_opt,
from_usize try_from_usize from_usize_truncated from_usize_unchecked,
as_usize try_as_usize as_usize_truncated);
}
impl<T: EnumSetType> Default for EnumSet<T> {
/// Returns an empty set.
fn default() -> Self {
Self::new()
}
}
impl<T: EnumSetType> IntoIterator for EnumSet<T> {
type Item = T;
type IntoIter = EnumSetIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T: EnumSetType> Sum for EnumSet<T> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | v)
}
}
impl<'a, T: EnumSetType> Sum<&'a EnumSet<T>> for EnumSet<T> {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | *v)
}
}
impl<T: EnumSetType> Sum<T> for EnumSet<T> {
fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | v)
}
}
impl<'a, T: EnumSetType> Sum<&'a T> for EnumSet<T> {
fn sum<I: Iterator<Item = &'a T>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | *v)
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> Sub<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn sub(self, other: O) -> Self::Output {
self.difference(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAnd<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitand(self, other: O) -> Self::Output {
self.intersection(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOr<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitor(self, other: O) -> Self::Output {
self.union(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXor<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitxor(self, other: O) -> Self::Output {
self.symmetrical_difference(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> SubAssign<O> for EnumSet<T> {
#[inline(always)]
fn sub_assign(&mut self, rhs: O) {
*self = *self - rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAndAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitand_assign(&mut self, rhs: O) {
*self = *self & rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOrAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitor_assign(&mut self, rhs: O) {
*self = *self | rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXorAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitxor_assign(&mut self, rhs: O) {
*self = *self ^ rhs;
}
}
impl<T: EnumSetType> Not for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn not(self) -> Self::Output {
self.complement()
}
}
impl<T: EnumSetType> From<T> for EnumSet<T> {
fn from(t: T) -> Self {
EnumSet::only(t)
}
}
impl<T: EnumSetType> PartialEq<T> for EnumSet<T> {
fn eq(&self, other: &T) -> bool {
self.__priv_repr == EnumSet::only(*other).__priv_repr
}
}
impl<T: EnumSetType + Debug> Debug for EnumSet<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let mut is_first = true;
f.write_str("EnumSet(")?;
for v in self.iter() {
if !is_first {
f.write_str(" | ")?;
}
is_first = false;
v.fmt(f)?;
}
f.write_str(")")?;
Ok(())
}
}
#[allow(clippy::derive_hash_xor_eq)] // This impl exists to change trait bounds only.
impl<T: EnumSetType> Hash for EnumSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.__priv_repr.hash(state)
}
}
impl<T: EnumSetType> PartialOrd for EnumSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.__priv_repr.partial_cmp(&other.__priv_repr)
}
}
impl<T: EnumSetType> Ord for EnumSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.__priv_repr.cmp(&other.__priv_repr)
}
}
#[cfg(feature = "serde")]
impl<T: EnumSetType> Serialize for EnumSet<T> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
T::serialize(*self, serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
T::deserialize(deserializer)
}
}
/// The iterator used by [`EnumSet`]s.
#[derive(Clone, Debug)]
pub struct EnumSetIter<T: EnumSetType> {
set: EnumSet<T>,
}
impl<T: EnumSetType> EnumSetIter<T> {
fn new(set: EnumSet<T>) -> EnumSetIter<T> {
EnumSetIter { set }
}
}
impl<T: EnumSetType> Iterator for EnumSetIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
if self.set.is_empty() {
None
} else {
let bit = self.set.__priv_repr.trailing_zeros();
self.set.__priv_repr.remove_bit(bit);
unsafe { Some(T::enum_from_u32(bit)) }
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let left = self.set.len();
(left, Some(left))
}
}
impl<T: EnumSetType> DoubleEndedIterator for EnumSetIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.set.is_empty() {
None
} else {
let bit = T::Repr::WIDTH - 1 - self.set.__priv_repr.leading_zeros();
self.set.__priv_repr.remove_bit(bit);
unsafe { Some(T::enum_from_u32(bit)) }
}
}
}
impl<T: EnumSetType> ExactSizeIterator for EnumSetIter<T> {}
impl<T: EnumSetType> Extend<T> for EnumSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
iter.into_iter().for_each(|v| {
self.insert(v);
});
}
}
impl<T: EnumSetType> FromIterator<T> for EnumSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut set = EnumSet::default();
set.extend(iter);
set
}
}
impl<T: EnumSetType> Extend<EnumSet<T>> for EnumSet<T> {
fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
iter.into_iter().for_each(|v| {
self.insert_all(v);
});
}
}
impl<T: EnumSetType> FromIterator<EnumSet<T>> for EnumSet<T> {
fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
let mut set = EnumSet::default();
set.extend(iter);
set
}
}
/// Creates a EnumSet literal, which can be used in const contexts.
///
/// The syntax used is `enum_set!(Type::A | Type::B | Type::C)`. Each variant must be of the same
/// type, or a error will occur at compile-time.
///
/// This macro accepts trailing `|`s to allow easier use in other macros.
///
/// # Examples
///
/// ```rust
/// # use enumset::*;
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
/// const CONST_SET: EnumSet<Enum> = enum_set!(Enum::A | Enum::B);
/// assert_eq!(CONST_SET, Enum::A | Enum::B);
/// ```
///
/// This macro is strongly typed. For example, the following will not compile:
///
/// ```compile_fail
/// # use enumset::*;
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
/// # #[derive(EnumSetType, Debug)] enum Enum2 { A, B, C }
/// let type_error = enum_set!(Enum::A | Enum2::B);
/// ```
#[macro_export]
macro_rules! enum_set {
($(|)*) => {
$crate::EnumSet { __priv_repr: 0 }
};
($value:path $(|)*) => {
{
#[allow(deprecated)] let value = $value.__impl_enumset_internal__const_only();
value
}
};
($value:path | $($rest:path)|* $(|)*) => {
{
#[allow(deprecated)] let value = $value.__impl_enumset_internal__const_only();
$(#[allow(deprecated)] let value = $rest.__impl_enumset_internal__const_merge(value);)*
value
}
};
}

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

@ -0,0 +1,60 @@
/// Everything in this module is internal API and may change at any time.
#[doc(hidden)]
pub mod __internal {
/// A reexport of core to allow our macros to be generic to std vs core.
pub use ::core as core_export;
/// A reexport of serde so our users don't have to also have a serde dependency.
#[cfg(feature = "serde")]
pub use serde2 as serde;
/// Reexports of internal types
pub use crate::{
repr::{ArrayRepr, EnumSetTypeRepr},
traits::EnumSetTypePrivate,
};
}
/// Creates a EnumSet literal, which can be used in const contexts.
///
/// The syntax used is `enum_set!(Type::A | Type::B | Type::C)`. Each variant must be of the same
/// type, or a error will occur at compile-time.
///
/// This macro accepts trailing `|`s to allow easier use in other macros.
///
/// # Examples
///
/// ```rust
/// # use enumset::*;
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
/// const CONST_SET: EnumSet<Enum> = enum_set!(Enum::A | Enum::B);
/// assert_eq!(CONST_SET, Enum::A | Enum::B);
/// ```
///
/// This macro is strongly typed. For example, the following will not compile:
///
/// ```compile_fail
/// # use enumset::*;
/// # #[derive(EnumSetType, Debug)] enum Enum { A, B, C }
/// # #[derive(EnumSetType, Debug)] enum Enum2 { A, B, C }
/// let type_error = enum_set!(Enum::A | Enum2::B);
/// ```
#[macro_export]
macro_rules! enum_set {
($(|)*) => {
EnumSet::EMPTY
};
($value:path $(|)*) => {
{
#[allow(deprecated)] let value = $value.__impl_enumset_internal__const_only();
value
}
};
($value:path | $($rest:path)|* $(|)*) => {
{
#[allow(deprecated)] let value = $value.__impl_enumset_internal__const_only();
$(#[allow(deprecated)] let value = $rest.__impl_enumset_internal__const_merge(value);)*
value
}
};
}

225
third_party/rust/enumset/src/repr.rs поставляемый
Просмотреть файл

@ -1,225 +0,0 @@
use core::convert::TryInto;
use core::fmt::Debug;
use core::hash::Hash;
use core::ops::*;
/// A trait marking valid underlying bitset storage types and providing the
/// operations `EnumSet` and related types use.
pub trait EnumSetTypeRepr :
// Basic traits used to derive traits
Copy +
Ord +
Eq +
Debug +
Hash +
// Operations used by enumset
BitAnd<Output = Self> +
BitOr<Output = Self> +
BitXor<Output = Self> +
Not<Output = Self> +
{
const WIDTH: u32;
fn is_empty(&self) -> bool;
fn empty() -> Self;
fn add_bit(&mut self, bit: u32);
fn remove_bit(&mut self, bit: u32);
fn has_bit(&self, bit: u32) -> bool;
fn count_ones(&self) -> u32;
fn count_remaining_ones(&self, cursor: u32) -> usize;
fn leading_zeros(&self) -> u32;
fn trailing_zeros(&self) -> u32;
fn and_not(&self, other: Self) -> Self;
fn from_u8(v: u8) -> Self;
fn from_u16(v: u16) -> Self;
fn from_u32(v: u32) -> Self;
fn from_u64(v: u64) -> Self;
fn from_u128(v: u128) -> Self;
fn from_usize(v: usize) -> Self;
fn to_u8(&self) -> u8;
fn to_u16(&self) -> u16;
fn to_u32(&self) -> u32;
fn to_u64(&self) -> u64;
fn to_u128(&self) -> u128;
fn to_usize(&self) -> usize;
fn from_u8_opt(v: u8) -> Option<Self>;
fn from_u16_opt(v: u16) -> Option<Self>;
fn from_u32_opt(v: u32) -> Option<Self>;
fn from_u64_opt(v: u64) -> Option<Self>;
fn from_u128_opt(v: u128) -> Option<Self>;
fn from_usize_opt(v: usize) -> Option<Self>;
fn to_u8_opt(&self) -> Option<u8>;
fn to_u16_opt(&self) -> Option<u16>;
fn to_u32_opt(&self) -> Option<u32>;
fn to_u64_opt(&self) -> Option<u64>;
fn to_u128_opt(&self) -> Option<u128>;
fn to_usize_opt(&self) -> Option<usize>;
}
macro_rules! prim {
($name:ty, $width:expr) => {
impl EnumSetTypeRepr for $name {
const WIDTH: u32 = $width;
#[inline(always)]
fn is_empty(&self) -> bool {
*self == 0
}
#[inline(always)]
fn empty() -> Self {
0
}
#[inline(always)]
fn add_bit(&mut self, bit: u32) {
*self |= 1 << bit as $name;
}
#[inline(always)]
fn remove_bit(&mut self, bit: u32) {
*self &= !(1 << bit as $name);
}
#[inline(always)]
fn has_bit(&self, bit: u32) -> bool {
(self & (1 << bit as $name)) != 0
}
#[inline(always)]
fn count_ones(&self) -> u32 {
(*self).count_ones()
}
#[inline(always)]
fn leading_zeros(&self) -> u32 {
(*self).leading_zeros()
}
#[inline(always)]
fn trailing_zeros(&self) -> u32 {
(*self).trailing_zeros()
}
#[inline(always)]
fn and_not(&self, other: Self) -> Self {
(*self) & !other
}
#[inline(always)]
fn count_remaining_ones(&self, cursor: u32) -> usize {
let left_mask = !((1 as $name)
.checked_shl(cursor)
.unwrap_or(0)
.wrapping_sub(1));
(*self & left_mask).count_ones() as usize
}
#[inline(always)]
fn from_u8(v: u8) -> Self {
v as $name
}
#[inline(always)]
fn from_u16(v: u16) -> Self {
v as $name
}
#[inline(always)]
fn from_u32(v: u32) -> Self {
v as $name
}
#[inline(always)]
fn from_u64(v: u64) -> Self {
v as $name
}
#[inline(always)]
fn from_u128(v: u128) -> Self {
v as $name
}
#[inline(always)]
fn from_usize(v: usize) -> Self {
v as $name
}
#[inline(always)]
fn to_u8(&self) -> u8 {
(*self) as u8
}
#[inline(always)]
fn to_u16(&self) -> u16 {
(*self) as u16
}
#[inline(always)]
fn to_u32(&self) -> u32 {
(*self) as u32
}
#[inline(always)]
fn to_u64(&self) -> u64 {
(*self) as u64
}
#[inline(always)]
fn to_u128(&self) -> u128 {
(*self) as u128
}
#[inline(always)]
fn to_usize(&self) -> usize {
(*self) as usize
}
#[inline(always)]
fn from_u8_opt(v: u8) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u16_opt(v: u16) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u32_opt(v: u32) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u64_opt(v: u64) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u128_opt(v: u128) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_usize_opt(v: usize) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn to_u8_opt(&self) -> Option<u8> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u16_opt(&self) -> Option<u16> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u32_opt(&self) -> Option<u32> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u64_opt(&self) -> Option<u64> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u128_opt(&self) -> Option<u128> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_usize_opt(&self) -> Option<usize> {
(*self).try_into().ok()
}
}
};
}
prim!(u8, 8);
prim!(u16, 16);
prim!(u32, 32);
prim!(u64, 64);
prim!(u128, 128);

335
third_party/rust/enumset/src/repr/array.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,335 @@
use crate::repr::primitive::PrimitiveIter;
use crate::repr::EnumSetTypeRepr;
use core::ops::*;
/// An implementation of `EnumSetTypeRepr` based on an arbitrary size array.
///
/// `N` **must** not be `0`, or else everything will break.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub struct ArrayRepr<const N: usize>(pub [u64; N]);
impl<const N: usize> ArrayRepr<N> {
fn split_bit(bit: u32) -> (usize, u32) {
(bit as usize / 64, bit % 64)
}
}
impl<const N: usize> BitAnd for ArrayRepr<N> {
type Output = Self;
fn bitand(mut self, rhs: Self) -> Self::Output {
for i in 0..N {
self.0[i] &= rhs.0[i];
}
self
}
}
impl<const N: usize> BitOr for ArrayRepr<N> {
type Output = Self;
fn bitor(mut self, rhs: Self) -> Self::Output {
for i in 0..N {
self.0[i] |= rhs.0[i];
}
self
}
}
impl<const N: usize> BitXor for ArrayRepr<N> {
type Output = Self;
fn bitxor(mut self, rhs: Self) -> Self::Output {
for i in 0..N {
self.0[i] ^= rhs.0[i];
}
self
}
}
impl<const N: usize> Not for ArrayRepr<N> {
type Output = Self;
fn not(mut self) -> Self::Output {
for i in 0..N {
self.0[i] = !self.0[i];
}
self
}
}
impl<const N: usize> EnumSetTypeRepr for ArrayRepr<N> {
const PREFERRED_ARRAY_LEN: usize = N;
const WIDTH: u32 = N as u32 * 64;
const EMPTY: Self = ArrayRepr([0; N]);
fn is_empty(&self) -> bool {
self.0.iter().all(|x| *x == 0)
}
fn add_bit(&mut self, bit: u32) {
let (idx, bit) = Self::split_bit(bit);
self.0[idx].add_bit(bit);
}
fn remove_bit(&mut self, bit: u32) {
let (idx, bit) = Self::split_bit(bit);
self.0[idx].remove_bit(bit);
}
fn has_bit(&self, bit: u32) -> bool {
let (idx, bit) = Self::split_bit(bit);
self.0[idx].has_bit(bit)
}
fn count_ones(&self) -> u32 {
self.0.iter().map(|x| x.count_ones()).sum()
}
fn leading_zeros(&self) -> u32 {
let mut accum = 0;
for i in (0..N).rev() {
if self.0[i] != 0 {
return accum + self.0[i].leading_zeros();
}
accum += 64;
}
Self::WIDTH
}
fn trailing_zeros(&self) -> u32 {
let mut accum = 0;
for i in 0..N {
if self.0[i] != 0 {
return accum + self.0[i].trailing_zeros();
}
accum += 64;
}
Self::WIDTH
}
fn and_not(&self, other: Self) -> Self {
let mut new = Self([0; N]);
for i in 0..N {
new.0[i] = self.0[i] & !other.0[i];
}
new
}
type Iter = ArrayIter<N>;
fn iter(self) -> Self::Iter {
ArrayIter::new(self)
}
fn from_u8(v: u8) -> Self {
Self::from_u64(v as u64)
}
fn from_u16(v: u16) -> Self {
Self::from_u64(v as u64)
}
fn from_u32(v: u32) -> Self {
Self::from_u64(v as u64)
}
fn from_u64(v: u64) -> Self {
let mut new = Self([0; N]);
new.0[0] = v;
new
}
fn from_u128(v: u128) -> Self {
let mut new = Self([0; N]);
new.0[0] = v as u64;
if N != 1 {
new.0[1] = (v >> 64) as u64;
}
new
}
fn from_usize(v: usize) -> Self {
Self::from_u64(v as u64)
}
fn from_u8_opt(v: u8) -> Option<Self> {
Some(Self::from_u8(v))
}
fn from_u16_opt(v: u16) -> Option<Self> {
Some(Self::from_u16(v))
}
fn from_u32_opt(v: u32) -> Option<Self> {
Some(Self::from_u32(v))
}
fn from_u64_opt(v: u64) -> Option<Self> {
Some(Self::from_u64(v))
}
fn from_u128_opt(v: u128) -> Option<Self> {
if N == 1 && (v >> 64) != 0 {
None
} else {
Some(Self::from_u128(v))
}
}
fn from_usize_opt(v: usize) -> Option<Self> {
Some(Self::from_usize(v))
}
fn to_u8(&self) -> u8 {
self.to_u64().to_u8()
}
fn to_u16(&self) -> u16 {
self.to_u64().to_u16()
}
fn to_u32(&self) -> u32 {
self.to_u64().to_u32()
}
fn to_u64(&self) -> u64 {
self.0[0]
}
fn to_u128(&self) -> u128 {
let hi = if N == 1 { 0 } else { (self.0[1] as u128) << 64 };
self.0[0] as u128 | hi
}
fn to_usize(&self) -> usize {
self.to_u64().to_usize()
}
fn to_u8_opt(&self) -> Option<u8> {
self.to_u64_opt().and_then(|x| x.to_u8_opt())
}
fn to_u16_opt(&self) -> Option<u16> {
self.to_u64_opt().and_then(|x| x.to_u16_opt())
}
fn to_u32_opt(&self) -> Option<u32> {
self.to_u64_opt().and_then(|x| x.to_u32_opt())
}
fn to_u64_opt(&self) -> Option<u64> {
for i in 1..N {
if self.0[i] != 0 {
return None;
}
}
Some(self.to_u64())
}
fn to_u128_opt(&self) -> Option<u128> {
for i in 2..N {
if self.0[i] != 0 {
return None;
}
}
Some(self.to_u128())
}
fn to_usize_opt(&self) -> Option<usize> {
self.to_u64_opt().and_then(|x| x.to_usize_opt())
}
fn to_u64_array<const O: usize>(&self) -> [u64; O] {
let mut array = [0; O];
let copy_len = if N < O { N } else { O };
array[..copy_len].copy_from_slice(&self.0[..copy_len]);
array
}
fn to_u64_array_opt<const O: usize>(&self) -> Option<[u64; O]> {
if N > O {
for i in O..N {
if self.0[i] != 0 {
return None;
}
}
}
Some(self.to_u64_array())
}
fn from_u64_array<const O: usize>(v: [u64; O]) -> Self {
ArrayRepr(ArrayRepr::<O>(v).to_u64_array::<N>())
}
fn from_u64_array_opt<const O: usize>(v: [u64; O]) -> Option<Self> {
ArrayRepr::<O>(v).to_u64_array_opt::<N>().map(ArrayRepr)
}
fn to_u64_slice(&self, out: &mut [u64]) {
let copy_len = if N < out.len() { N } else { out.len() };
out[..copy_len].copy_from_slice(&self.0[..copy_len]);
for i in copy_len..out.len() {
out[i] = 0;
}
}
#[must_use]
fn to_u64_slice_opt(&self, out: &mut [u64]) -> Option<()> {
if N > out.len() {
for i in out.len()..N {
if self.0[i] != 0 {
return None;
}
}
}
self.to_u64_slice(out);
Some(())
}
fn from_u64_slice(v: &[u64]) -> Self {
let mut new = ArrayRepr([0; N]);
let copy_len = if N < v.len() { N } else { v.len() };
new.0[..copy_len].copy_from_slice(&v[..copy_len]);
new
}
fn from_u64_slice_opt(v: &[u64]) -> Option<Self> {
if v.len() > N {
for i in N..v.len() {
if v[i] != 0 {
return None;
}
}
}
Some(Self::from_u64_slice(v))
}
}
#[derive(Clone, Debug)]
pub struct ArrayIter<const N: usize> {
data: [PrimitiveIter<u64>; N],
done: bool,
idx_f: usize,
idx_r: usize,
}
impl<const N: usize> ArrayIter<N> {
pub fn new(array: ArrayRepr<N>) -> Self {
let mut new = [PrimitiveIter(0); N];
for i in 0..N {
new[i] = PrimitiveIter(array.0[i])
}
ArrayIter { data: new, done: false, idx_f: 0, idx_r: N - 1 }
}
}
impl<const N: usize> Iterator for ArrayIter<N> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
while self.idx_f <= self.idx_r {
if let Some(x) = self.data[self.idx_f].next() {
return Some(self.idx_f as u32 * 64 + x);
} else {
self.idx_f += 1;
}
}
self.done = true;
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
let mut sum = 0;
for i in self.idx_f..self.idx_r + 1 {
sum += self.data[i].0.count_ones() as usize;
}
(sum, Some(sum))
}
}
impl<const N: usize> DoubleEndedIterator for ArrayIter<N> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
while self.idx_f <= self.idx_r {
if let Some(x) = self.data[self.idx_r].next_back() {
return Some(self.idx_r as u32 * 64 + x);
} else {
if self.idx_r == 0 {
break;
}
self.idx_r -= 1;
}
}
self.done = true;
None
}
}

92
third_party/rust/enumset/src/repr/mod.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,92 @@
#![allow(missing_docs)]
mod array;
mod primitive;
use core::fmt::Debug;
use core::hash::Hash;
use core::ops::*;
/// A trait marking valid underlying bitset storage types and providing the
/// operations `EnumSet` and related types use.
///
/// # Safety
///
/// Note that `iter` *MUST* be implemented correctly and only return bits that
/// are actually set in the representation, or else it will cause undefined
/// behavior upstream in `EnumSet`.
pub trait EnumSetTypeRepr :
// Basic traits used to derive traits
Copy +
Ord +
Eq +
Debug +
Hash +
// Operations used by enumset
BitAnd<Output = Self> +
BitOr<Output = Self> +
BitXor<Output = Self> +
Not<Output = Self> +
{
const PREFERRED_ARRAY_LEN: usize;
const WIDTH: u32;
const EMPTY: Self;
fn is_empty(&self) -> bool;
fn add_bit(&mut self, bit: u32);
fn remove_bit(&mut self, bit: u32);
fn has_bit(&self, bit: u32) -> bool;
fn count_ones(&self) -> u32;
fn leading_zeros(&self) -> u32;
fn trailing_zeros(&self) -> u32;
fn and_not(&self, other: Self) -> Self;
type Iter: Iterator<Item = u32> + DoubleEndedIterator + Clone + Debug;
fn iter(self) -> Self::Iter;
fn from_u8(v: u8) -> Self;
fn from_u16(v: u16) -> Self;
fn from_u32(v: u32) -> Self;
fn from_u64(v: u64) -> Self;
fn from_u128(v: u128) -> Self;
fn from_usize(v: usize) -> Self;
fn to_u8(&self) -> u8;
fn to_u16(&self) -> u16;
fn to_u32(&self) -> u32;
fn to_u64(&self) -> u64;
fn to_u128(&self) -> u128;
fn to_usize(&self) -> usize;
fn from_u8_opt(v: u8) -> Option<Self>;
fn from_u16_opt(v: u16) -> Option<Self>;
fn from_u32_opt(v: u32) -> Option<Self>;
fn from_u64_opt(v: u64) -> Option<Self>;
fn from_u128_opt(v: u128) -> Option<Self>;
fn from_usize_opt(v: usize) -> Option<Self>;
fn to_u8_opt(&self) -> Option<u8>;
fn to_u16_opt(&self) -> Option<u16>;
fn to_u32_opt(&self) -> Option<u32>;
fn to_u64_opt(&self) -> Option<u64>;
fn to_u128_opt(&self) -> Option<u128>;
fn to_usize_opt(&self) -> Option<usize>;
fn to_u64_array<const O: usize>(&self) -> [u64; O];
fn to_u64_array_opt<const O: usize>(&self) -> Option<[u64; O]>;
fn from_u64_array<const O: usize>(v: [u64; O]) -> Self;
fn from_u64_array_opt<const O: usize>(v: [u64; O]) -> Option<Self>;
fn to_u64_slice(&self, out: &mut [u64]);
#[must_use]
fn to_u64_slice_opt(&self, out: &mut [u64]) -> Option<()>;
fn from_u64_slice(v: &[u64]) -> Self;
fn from_u64_slice_opt(v: &[u64]) -> Option<Self>;
}
pub use array::ArrayRepr;

300
third_party/rust/enumset/src/repr/primitive.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,300 @@
use crate::repr::EnumSetTypeRepr;
macro_rules! prim {
($name:ty, $width:expr, $preferred_array_len:expr) => {
const _: () = {
fn lo(v: $name) -> u64 {
v as u64
}
fn hi(v: $name) -> u64 {
((v as u128) >> 64) as u64
}
impl EnumSetTypeRepr for $name {
const PREFERRED_ARRAY_LEN: usize = $preferred_array_len;
const WIDTH: u32 = $width;
const EMPTY: Self = 0;
#[inline(always)]
fn is_empty(&self) -> bool {
*self == 0
}
#[inline(always)]
fn add_bit(&mut self, bit: u32) {
*self |= 1 << bit as $name;
}
#[inline(always)]
fn remove_bit(&mut self, bit: u32) {
*self &= !(1 << bit as $name);
}
#[inline(always)]
fn has_bit(&self, bit: u32) -> bool {
(self & (1 << bit as $name)) != 0
}
#[inline(always)]
fn count_ones(&self) -> u32 {
(*self).count_ones()
}
#[inline(always)]
fn leading_zeros(&self) -> u32 {
(*self).leading_zeros()
}
#[inline(always)]
fn trailing_zeros(&self) -> u32 {
(*self).trailing_zeros()
}
#[inline(always)]
fn and_not(&self, other: Self) -> Self {
(*self) & !other
}
type Iter = PrimitiveIter<Self>;
fn iter(self) -> Self::Iter {
PrimitiveIter(self)
}
#[inline(always)]
fn from_u8(v: u8) -> Self {
v as $name
}
#[inline(always)]
fn from_u16(v: u16) -> Self {
v as $name
}
#[inline(always)]
fn from_u32(v: u32) -> Self {
v as $name
}
#[inline(always)]
fn from_u64(v: u64) -> Self {
v as $name
}
#[inline(always)]
fn from_u128(v: u128) -> Self {
v as $name
}
#[inline(always)]
fn from_usize(v: usize) -> Self {
v as $name
}
#[inline(always)]
fn to_u8(&self) -> u8 {
(*self) as u8
}
#[inline(always)]
fn to_u16(&self) -> u16 {
(*self) as u16
}
#[inline(always)]
fn to_u32(&self) -> u32 {
(*self) as u32
}
#[inline(always)]
fn to_u64(&self) -> u64 {
(*self) as u64
}
#[inline(always)]
fn to_u128(&self) -> u128 {
(*self) as u128
}
#[inline(always)]
fn to_usize(&self) -> usize {
(*self) as usize
}
#[inline(always)]
fn from_u8_opt(v: u8) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u16_opt(v: u16) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u32_opt(v: u32) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u64_opt(v: u64) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_u128_opt(v: u128) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn from_usize_opt(v: usize) -> Option<Self> {
v.try_into().ok()
}
#[inline(always)]
fn to_u8_opt(&self) -> Option<u8> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u16_opt(&self) -> Option<u16> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u32_opt(&self) -> Option<u32> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u64_opt(&self) -> Option<u64> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u128_opt(&self) -> Option<u128> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_usize_opt(&self) -> Option<usize> {
(*self).try_into().ok()
}
#[inline(always)]
fn to_u64_array<const O: usize>(&self) -> [u64; O] {
let mut array = [0; O];
if O > 0 {
array[0] = lo(*self);
}
if O > 1 && $preferred_array_len == 2 {
array[1] = hi(*self);
}
array
}
#[inline(always)]
fn to_u64_array_opt<const O: usize>(&self) -> Option<[u64; O]> {
if O == 0 && *self != 0 {
None
} else if O == 1 && hi(*self) != 0 {
None
} else {
Some(self.to_u64_array())
}
}
#[inline(always)]
fn from_u64_array<const O: usize>(v: [u64; O]) -> Self {
if O == 0 {
0
} else if O > 1 && $preferred_array_len == 2 {
Self::from_u128(v[0] as u128 | ((v[1] as u128) << 64))
} else {
Self::from_u64(v[0])
}
}
#[inline(always)]
fn from_u64_array_opt<const O: usize>(v: [u64; O]) -> Option<Self> {
if O == 0 {
Some(0)
} else if O == 1 {
Self::from_u64_opt(v[0])
} else {
for i in 2..O {
if v[i] != 0 {
return None;
}
}
Self::from_u128_opt(v[0] as u128 | ((v[1] as u128) << 64))
}
}
#[inline(always)]
fn to_u64_slice(&self, out: &mut [u64]) {
if out.len() > 0 {
out[0] = lo(*self);
}
if out.len() > 1 && $preferred_array_len == 2 {
out[1] = hi(*self);
}
for i in $preferred_array_len..out.len() {
out[i] = 0;
}
}
#[inline(always)]
#[must_use]
fn to_u64_slice_opt(&self, out: &mut [u64]) -> Option<()> {
if out.len() == 0 && *self != 0 {
None
} else if out.len() == 1 && hi(*self) != 0 {
None
} else {
self.to_u64_slice(out);
Some(())
}
}
#[inline(always)]
fn from_u64_slice(v: &[u64]) -> Self {
if v.len() == 0 {
0
} else if v.len() > 1 && $preferred_array_len == 2 {
Self::from_u128(v[0] as u128 | ((v[1] as u128) << 64))
} else {
Self::from_u64(v[0])
}
}
#[inline(always)]
fn from_u64_slice_opt(v: &[u64]) -> Option<Self> {
if v.len() == 0 {
Some(0)
} else if v.len() == 1 {
Self::from_u64_opt(v[0])
} else {
for i in 2..v.len() {
if v[i] != 0 {
return None;
}
}
Self::from_u128_opt(v[0] as u128 | ((v[1] as u128) << 64))
}
}
}
};
};
}
prim!(u8, 8, 1);
prim!(u16, 16, 1);
prim!(u32, 32, 1);
prim!(u64, 64, 1);
prim!(u128, 128, 2);
#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
pub struct PrimitiveIter<T: EnumSetTypeRepr>(pub T);
impl<T: EnumSetTypeRepr> Iterator for PrimitiveIter<T> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.0.is_empty() {
None
} else {
let bit = self.0.trailing_zeros();
self.0.remove_bit(bit);
Some(bit)
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let left = self.0.count_ones() as usize;
(left, Some(left))
}
}
impl<T: EnumSetTypeRepr> DoubleEndedIterator for PrimitiveIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
if self.0.is_empty() {
None
} else {
let bit = T::WIDTH - 1 - self.0.leading_zeros();
self.0.remove_bit(bit);
Some(bit)
}
}
}

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

@ -0,0 +1,856 @@
use crate::repr::EnumSetTypeRepr;
use crate::traits::EnumSetType;
use crate::EnumSetTypeWithRepr;
use core::cmp::Ordering;
use core::fmt::{Debug, Formatter};
use core::hash::{Hash, Hasher};
use core::iter::Sum;
use core::ops::{
BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Not, Sub, SubAssign,
};
#[cfg(feature = "serde")]
use {
serde2 as serde,
serde2::{Deserialize, Serialize},
};
/// An efficient set type for enums.
///
/// It is implemented using a bitset stored using the smallest integer that can fit all bits
/// in the underlying enum. In general, an enum variant with a discriminator of `n` is stored in
/// the nth least significant bit (corresponding with a mask of, e.g. `1 << enum as u32`).
///
/// # Numeric representation
///
/// `EnumSet` is internally implemented using integer types, and as such can be easily converted
/// from and to numbers.
///
/// Each bit of the underlying integer corresponds to at most one particular enum variant. If the
/// corresponding bit for a variant is set, it present in the set. Bits that do not correspond to
/// any variant are always unset.
///
/// By default, each enum variant is stored in a bit corresponding to its discriminator. An enum
/// variant with a discriminator of `n` is stored in the `n + 1`th least significant bit
/// (corresponding to a mask of e.g. `1 << enum as u32`).
///
/// # Array representation
///
/// Sets with more than 128 variants are instead stored with an underlying array of `u64`s. This
/// is treated as if it was a single large integer. The `n`th least significant bit of this integer
/// is stored in the `n % 64`th least significant bit of the `n / 64`th element in the array.
///
/// # Serialization
///
/// When the `serde` feature is enabled, `EnumSet`s can be serialized and deserialized using
/// the `serde` crate. The exact serialization format can be controlled with additional attributes
/// on the enum type. These attributes are valid regardless of whether the `serde` feature
/// is enabled.
///
/// By default, `EnumSet` is serialized by directly writing out a single integer containing the
/// numeric representation of the bitset. The integer type used is the smallest one that can fit
/// the largest variant in the enum. If no integer type is large enough, instead the `EnumSet` is
/// serialized as an array of `u64`s containing the array representation.
///
/// The `#[enumset(serialize_repr = "…")]` attribute can be used to override the representation
/// used. Valid values are as follows:
///
/// * `u8`, `u16`, `u32`, `u64`, and `u128` serialize the type as the corresponding integer type.
/// * `array` serializes the set as an list of `u64`s corresponding to the array representation.
/// * `list` serializes the set as a list of enum variants. This requires your enum type implement
/// [`Serialize`] and [`Deserialize`].
/// * `map` serializes the set as a map of enum variants to booleans. The set contains a value if
/// the boolean is `true`. This requires your enum type implement `Serialize` and `Deserialize`.
///
/// The representation used is determined statically at compile time, and there is currently no
/// support for reading different formats with the same deserializer.
///
/// By default, unknown bits are ignored and silently removed from the bitset. To override this
/// behavior, you can add a `#[enumset(serialize_deny_unknown)]` attribute. This will cause
/// deserialization to fail if an invalid bit is set.
///
/// # FFI, Safety and `repr`
///
/// If an enum type `T` is annotated with
/// [`#[enumset(repr = "…")]`](derive@crate::EnumSetType#options) where `…` is a primitive integer
/// type, then several things happen:
///
/// * `T` will implement
/// <code>[EnumSetTypeWithRepr](crate::traits::EnumSetTypeWithRepr)&lt;Repr = R&gt;</code> in
/// addition to [`EnumSetType`].
/// * The `EnumSet` methods with `repr` in their name, such as [`as_repr`][EnumSet::as_repr] and
/// [`from_repr`][EnumSet::from_repr], will be available for `EnumSet<T>`.
/// * The in-memory representation of `EnumSet<T>` is guaranteed to be `R`.
///
/// That last guarantee makes it sound to send `EnumSet<T>` across an FFI boundary. For example:
///
/// ```
/// # use enumset::*;
/// #
/// # mod ffi_impl {
/// # // This example “foreign” function is actually written in Rust, but for the sake
/// # // of example, we'll pretend it's written in C.
/// # #[no_mangle]
/// # extern "C" fn some_foreign_function(set: u32) -> u32 {
/// # set & 0b100
/// # }
/// # }
/// #
/// extern "C" {
/// // This function is written in C like:
/// // uint32_t some_foreign_function(uint32_t set) { … }
/// fn some_foreign_function(set: EnumSet<MyEnum>) -> EnumSet<MyEnum>;
/// }
///
/// #[derive(Debug, EnumSetType)]
/// #[enumset(repr = "u32")]
/// enum MyEnum { A, B, C }
///
/// let set: EnumSet<MyEnum> = enum_set!(MyEnum::A | MyEnum::C);
///
/// let new_set: EnumSet<MyEnum> = unsafe { some_foreign_function(set) };
/// assert_eq!(new_set, enum_set!(MyEnum::C));
/// ```
///
/// When an `EnumSet<T>` is received via FFI, all bits that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set to `1`.
#[cfg_attr(
not(feature = "serde"),
doc = "\n\n",
doc = "[`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html\n",
doc = "[`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html\n"
)]
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(transparent)]
pub struct EnumSet<T: EnumSetType> {
#[doc(hidden)]
/// This is public due to the `enum_set!` macro.
/// This is **NOT** public API and may change at any time.
pub __priv_repr: T::Repr,
}
//region EnumSet operations
impl<T: EnumSetType> EnumSet<T> {
/// An empty `EnumSet`.
///
/// This is available as a constant for use in constant expressions.
pub const EMPTY: Self = EnumSet { __priv_repr: T::Repr::EMPTY };
/// An `EnumSet` containing all valid variants of the enum.
///
/// This is available as a constant for use in constant expressions.
pub const ALL: Self = EnumSet { __priv_repr: T::ALL_BITS };
/// Creates an empty `EnumSet`.
#[inline(always)]
pub fn new() -> Self {
Self::EMPTY
}
/// Returns an `EnumSet` containing a single element.
#[inline(always)]
pub fn only(t: T) -> Self {
let mut set = Self::new();
set.insert(t);
set
}
/// Creates an empty `EnumSet`.
///
/// This is an alias for [`EnumSet::new`].
#[inline(always)]
pub fn empty() -> Self {
Self::EMPTY
}
/// Returns an `EnumSet` containing all valid variants of the enum.
#[inline(always)]
pub fn all() -> Self {
Self::ALL
}
/// Total number of bits used by this type. Note that the actual amount of space used is
/// rounded up to the next highest integer type (`u8`, `u16`, `u32`, `u64`, or `u128`).
///
/// This is the same as [`EnumSet::variant_count`] except in enums with "sparse" variants.
/// (e.g. `enum Foo { A = 10, B = 20 }`)
#[inline(always)]
pub fn bit_width() -> u32 {
T::BIT_WIDTH
}
/// The number of valid variants that this type can contain.
///
/// This is the same as [`EnumSet::bit_width`] except in enums with "sparse" variants.
/// (e.g. `enum Foo { A = 10, B = 20 }`)
#[inline(always)]
pub fn variant_count() -> u32 {
T::VARIANT_COUNT
}
/// Returns the number of elements in this set.
#[inline(always)]
pub fn len(&self) -> usize {
self.__priv_repr.count_ones() as usize
}
/// Returns `true` if the set contains no elements.
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.__priv_repr.is_empty()
}
/// Removes all elements from the set.
#[inline(always)]
pub fn clear(&mut self) {
self.__priv_repr = T::Repr::EMPTY;
}
/// Returns `true` if `self` has no elements in common with `other`. This is equivalent to
/// checking for an empty intersection.
#[inline(always)]
pub fn is_disjoint(&self, other: Self) -> bool {
(*self & other).is_empty()
}
/// Returns `true` if the set is a superset of another, i.e., `self` contains at least all the
/// values in `other`.
#[inline(always)]
pub fn is_superset(&self, other: Self) -> bool {
(*self & other).__priv_repr == other.__priv_repr
}
/// Returns `true` if the set is a subset of another, i.e., `other` contains at least all
/// the values in `self`.
#[inline(always)]
pub fn is_subset(&self, other: Self) -> bool {
other.is_superset(*self)
}
/// Returns a set containing any elements present in either set.
#[inline(always)]
pub fn union(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr | other.__priv_repr }
}
/// Returns a set containing every element present in both sets.
#[inline(always)]
pub fn intersection(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr & other.__priv_repr }
}
/// Returns a set containing element present in `self` but not in `other`.
#[inline(always)]
pub fn difference(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr.and_not(other.__priv_repr) }
}
/// Returns a set containing every element present in either `self` or `other`, but is not
/// present in both.
#[inline(always)]
pub fn symmetrical_difference(&self, other: Self) -> Self {
EnumSet { __priv_repr: self.__priv_repr ^ other.__priv_repr }
}
/// Returns a set containing all enum variants not in this set.
#[inline(always)]
pub fn complement(&self) -> Self {
EnumSet { __priv_repr: !self.__priv_repr & T::ALL_BITS }
}
/// Checks whether this set contains a value.
#[inline(always)]
pub fn contains(&self, value: T) -> bool {
self.__priv_repr.has_bit(value.enum_into_u32())
}
/// Adds a value to this set.
///
/// If the set did not have this value present, `true` is returned.
///
/// If the set did have this value present, `false` is returned.
#[inline(always)]
pub fn insert(&mut self, value: T) -> bool {
let contains = !self.contains(value);
self.__priv_repr.add_bit(value.enum_into_u32());
contains
}
/// Removes a value from this set. Returns whether the value was present in the set.
#[inline(always)]
pub fn remove(&mut self, value: T) -> bool {
let contains = self.contains(value);
self.__priv_repr.remove_bit(value.enum_into_u32());
contains
}
/// Adds all elements in another set to this one.
#[inline(always)]
pub fn insert_all(&mut self, other: Self) {
self.__priv_repr = self.__priv_repr | other.__priv_repr
}
/// Removes all values in another set from this one.
#[inline(always)]
pub fn remove_all(&mut self, other: Self) {
self.__priv_repr = self.__priv_repr.and_not(other.__priv_repr);
}
}
impl<T: EnumSetType> Default for EnumSet<T> {
/// Returns an empty set.
fn default() -> Self {
Self::new()
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> Sub<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn sub(self, other: O) -> Self::Output {
self.difference(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAnd<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitand(self, other: O) -> Self::Output {
self.intersection(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOr<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitor(self, other: O) -> Self::Output {
self.union(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXor<O> for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn bitxor(self, other: O) -> Self::Output {
self.symmetrical_difference(other.into())
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> SubAssign<O> for EnumSet<T> {
#[inline(always)]
fn sub_assign(&mut self, rhs: O) {
*self = *self - rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitAndAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitand_assign(&mut self, rhs: O) {
*self = *self & rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitOrAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitor_assign(&mut self, rhs: O) {
*self = *self | rhs;
}
}
impl<T: EnumSetType, O: Into<EnumSet<T>>> BitXorAssign<O> for EnumSet<T> {
#[inline(always)]
fn bitxor_assign(&mut self, rhs: O) {
*self = *self ^ rhs;
}
}
impl<T: EnumSetType> Not for EnumSet<T> {
type Output = Self;
#[inline(always)]
fn not(self) -> Self::Output {
self.complement()
}
}
impl<T: EnumSetType> From<T> for EnumSet<T> {
fn from(t: T) -> Self {
EnumSet::only(t)
}
}
impl<T: EnumSetType> PartialEq<T> for EnumSet<T> {
fn eq(&self, other: &T) -> bool {
self.__priv_repr == EnumSet::only(*other).__priv_repr
}
}
impl<T: EnumSetType + Debug> Debug for EnumSet<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
let mut is_first = true;
f.write_str("EnumSet(")?;
for v in self.iter() {
if !is_first {
f.write_str(" | ")?;
}
is_first = false;
v.fmt(f)?;
}
f.write_str(")")?;
Ok(())
}
}
#[allow(clippy::derived_hash_with_manual_eq)] // This impl exists to change trait bounds only.
impl<T: EnumSetType> Hash for EnumSet<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.__priv_repr.hash(state)
}
}
impl<T: EnumSetType> PartialOrd for EnumSet<T> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.__priv_repr.partial_cmp(&other.__priv_repr)
}
}
impl<T: EnumSetType> Ord for EnumSet<T> {
fn cmp(&self, other: &Self) -> Ordering {
self.__priv_repr.cmp(&other.__priv_repr)
}
}
#[cfg(feature = "serde")]
impl<T: EnumSetType> Serialize for EnumSet<T> {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
T::serialize(*self, serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T: EnumSetType> Deserialize<'de> for EnumSet<T> {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
T::deserialize(deserializer)
}
}
//endregion
//region EnumSet conversions
impl<T: EnumSetType + EnumSetTypeWithRepr> EnumSet<T> {
/// Returns a `T::Repr` representing the elements of this set.
///
/// Unlike the other `as_*` methods, this method is zero-cost and guaranteed not to fail,
/// panic or truncate any bits.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn as_repr(&self) -> <T as EnumSetTypeWithRepr>::Repr {
self.__priv_repr
}
/// Constructs a bitset from a `T::Repr` without checking for invalid bits.
///
/// Unlike the other `from_*` methods, this method is zero-cost and guaranteed not to fail,
/// panic or truncate any bits, provided the conditions under “Safety” are upheld.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant of
/// `T` must be set to `0`. Behavior is **undefined** if any of these bits are set to `1`.
#[inline(always)]
pub unsafe fn from_repr_unchecked(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
Self { __priv_repr: bits }
}
/// Constructs a bitset from a `T::Repr`.
///
/// If a bit that doesn't correspond to an enum variant is set, this
/// method will panic.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
Self::try_from_repr(bits).expect("Bitset contains invalid variants.")
}
/// Attempts to constructs a bitset from a `T::Repr`.
///
/// If a bit that doesn't correspond to an enum variant is set, this
/// method will return `None`.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn try_from_repr(bits: <T as EnumSetTypeWithRepr>::Repr) -> Option<Self> {
let mask = Self::all().__priv_repr;
if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
}
}
/// Constructs a bitset from a `T::Repr`, ignoring invalid variants.
///
/// In order to use this method, the definition of `T` must have the `#[enumset(repr = "…")]`
/// annotation.
#[inline(always)]
pub fn from_repr_truncated(bits: <T as EnumSetTypeWithRepr>::Repr) -> Self {
let mask = Self::all().as_repr();
let bits = bits & mask;
EnumSet { __priv_repr: bits }
}
}
/// Helper macro for generating conversion functions.
macro_rules! conversion_impls {
(
$(for_num!(
$underlying:ty, $underlying_str:expr,
$from_fn:ident $to_fn:ident $from_fn_opt:ident $to_fn_opt:ident,
$from:ident $try_from:ident $from_truncated:ident $from_unchecked:ident,
$to:ident $try_to:ident $to_truncated:ident
);)*
) => {
impl<T: EnumSetType> EnumSet<T> {$(
#[doc = "Returns a `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "`, this method will panic."]
#[inline(always)]
pub fn $to(&self) -> $underlying {
self.$try_to().expect("Bitset will not fit into this type.")
}
#[doc = "Tries to return a `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "`, this method will panic."]
#[inline(always)]
pub fn $try_to(&self) -> Option<$underlying> {
EnumSetTypeRepr::$to_fn_opt(&self.__priv_repr)
}
#[doc = "Returns a truncated `"]
#[doc = $underlying_str]
#[doc = "` representing the elements of this set.\n\nIf the underlying bitset will \
not fit in a `"]
#[doc = $underlying_str]
#[doc = "`, this method will truncate any bits that don't fit."]
#[inline(always)]
pub fn $to_truncated(&self) -> $underlying {
EnumSetTypeRepr::$to_fn(&self.__priv_repr)
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
method will panic."]
#[inline(always)]
pub fn $from(bits: $underlying) -> Self {
Self::$try_from(bits).expect("Bitset contains invalid variants.")
}
#[doc = "Attempts to constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`.\n\nIf a bit that doesn't correspond to an enum variant is set, this \
method will return `None`."]
#[inline(always)]
pub fn $try_from(bits: $underlying) -> Option<Self> {
let bits = T::Repr::$from_fn_opt(bits);
let mask = T::ALL_BITS;
bits.and_then(|bits| if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
})
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`, ignoring bits that do not correspond to a variant."]
#[inline(always)]
pub fn $from_truncated(bits: $underlying) -> Self {
let mask = Self::all().$to_truncated();
let bits = <T::Repr as EnumSetTypeRepr>::$from_fn(bits & mask);
EnumSet { __priv_repr: bits }
}
#[doc = "Constructs a bitset from a `"]
#[doc = $underlying_str]
#[doc = "`, without checking for invalid bits."]
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set
/// to `1`.
#[inline(always)]
pub unsafe fn $from_unchecked(bits: $underlying) -> Self {
EnumSet { __priv_repr: <T::Repr as EnumSetTypeRepr>::$from_fn(bits) }
}
)*}
}
}
conversion_impls! {
for_num!(u8, "u8",
from_u8 to_u8 from_u8_opt to_u8_opt,
from_u8 try_from_u8 from_u8_truncated from_u8_unchecked,
as_u8 try_as_u8 as_u8_truncated);
for_num!(u16, "u16",
from_u16 to_u16 from_u16_opt to_u16_opt,
from_u16 try_from_u16 from_u16_truncated from_u16_unchecked,
as_u16 try_as_u16 as_u16_truncated);
for_num!(u32, "u32",
from_u32 to_u32 from_u32_opt to_u32_opt,
from_u32 try_from_u32 from_u32_truncated from_u32_unchecked,
as_u32 try_as_u32 as_u32_truncated);
for_num!(u64, "u64",
from_u64 to_u64 from_u64_opt to_u64_opt,
from_u64 try_from_u64 from_u64_truncated from_u64_unchecked,
as_u64 try_as_u64 as_u64_truncated);
for_num!(u128, "u128",
from_u128 to_u128 from_u128_opt to_u128_opt,
from_u128 try_from_u128 from_u128_truncated from_u128_unchecked,
as_u128 try_as_u128 as_u128_truncated);
for_num!(usize, "usize",
from_usize to_usize from_usize_opt to_usize_opt,
from_usize try_from_usize from_usize_truncated from_usize_unchecked,
as_usize try_as_usize as_usize_truncated);
}
impl<T: EnumSetType> EnumSet<T> {
/// Returns an `[u64; O]` representing the elements of this set.
///
/// If the underlying bitset will not fit in a `[u64; O]`, this method will panic.
pub fn as_array<const O: usize>(&self) -> [u64; O] {
self.try_as_array()
.expect("Bitset will not fit into this type.")
}
/// Returns an `[u64; O]` representing the elements of this set.
///
/// If the underlying bitset will not fit in a `[u64; O]`, this method will instead return
/// `None`.
pub fn try_as_array<const O: usize>(&self) -> Option<[u64; O]> {
self.__priv_repr.to_u64_array_opt()
}
/// Returns an `[u64; O]` representing the elements of this set.
///
/// If the underlying bitset will not fit in a `[u64; O]`, this method will truncate any bits
/// that don't fit.
pub fn as_array_truncated<const O: usize>(&self) -> [u64; O] {
self.__priv_repr.to_u64_array()
}
/// Attempts to constructs a bitset from a `[u64; O]`.
///
/// If a bit that doesn't correspond to an enum variant is set, this method will panic.
pub fn from_array<const O: usize>(v: [u64; O]) -> Self {
Self::try_from_array(v).expect("Bitset contains invalid variants.")
}
/// Attempts to constructs a bitset from a `[u64; O]`.
///
/// If a bit that doesn't correspond to an enum variant is set, this method will return `None`.
pub fn try_from_array<const O: usize>(bits: [u64; O]) -> Option<Self> {
let bits = T::Repr::from_u64_array_opt::<O>(bits);
let mask = T::ALL_BITS;
bits.and_then(|bits| {
if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
}
})
}
/// Constructs a bitset from a `[u64; O]`, ignoring bits that do not correspond to a variant.
pub fn from_array_truncated<const O: usize>(bits: [u64; O]) -> Self {
let bits = T::Repr::from_u64_array(bits) & T::ALL_BITS;
EnumSet { __priv_repr: bits }
}
/// Constructs a bitset from a `[u64; O]`, without checking for invalid bits.
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set
/// to `1`.
#[inline(always)]
pub unsafe fn from_array_unchecked<const O: usize>(bits: [u64; O]) -> Self {
EnumSet { __priv_repr: T::Repr::from_u64_array(bits) }
}
/// Returns a `Vec<u64>` representing the elements of this set.
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
pub fn to_vec(&self) -> alloc::vec::Vec<u64> {
let mut vec = alloc::vec![0; T::Repr::PREFERRED_ARRAY_LEN];
self.__priv_repr.to_u64_slice(&mut vec);
vec
}
/// Copies the elements of this set into a `&mut [u64]`.
///
/// If the underlying bitset will not fit in the provided slice, this method will panic.
pub fn copy_into_slice(&self, data: &mut [u64]) {
self.try_copy_into_slice(data)
.expect("Bitset will not fit into slice.")
}
/// Copies the elements of this set into a `&mut [u64]`.
///
/// If the underlying bitset will not fit in the provided slice, this method will return
/// `None`. Otherwise, it will return `Some(())`.
#[must_use]
pub fn try_copy_into_slice(&self, data: &mut [u64]) -> Option<()> {
self.__priv_repr.to_u64_slice_opt(data)
}
/// Copies the elements of this set into a `&mut [u64]`.
///
/// If the underlying bitset will not fit in the provided slice, this method will truncate any
/// bits that don't fit.
pub fn copy_into_slice_truncated(&self, data: &mut [u64]) {
self.__priv_repr.to_u64_slice(data)
}
/// Attempts to constructs a bitset from a `&[u64]`.
///
/// If a bit that doesn't correspond to an enum variant is set, this method will panic.
pub fn from_slice(v: &[u64]) -> Self {
Self::try_from_slice(v).expect("Bitset contains invalid variants.")
}
/// Attempts to constructs a bitset from a `&[u64]`.
///
/// If a bit that doesn't correspond to an enum variant is set, this method will return `None`.
pub fn try_from_slice(bits: &[u64]) -> Option<Self> {
let bits = T::Repr::from_u64_slice_opt(bits);
let mask = T::ALL_BITS;
bits.and_then(|bits| {
if bits.and_not(mask).is_empty() {
Some(EnumSet { __priv_repr: bits })
} else {
None
}
})
}
/// Constructs a bitset from a `&[u64]`, ignoring bits that do not correspond to a variant.
pub fn from_slice_truncated(bits: &[u64]) -> Self {
let bits = T::Repr::from_u64_slice(bits) & T::ALL_BITS;
EnumSet { __priv_repr: bits }
}
/// Constructs a bitset from a `&[u64]`, without checking for invalid bits.
///
/// # Safety
///
/// All bits in the provided parameter `bits` that don't correspond to an enum variant
/// of `T` must be set to `0`. Behavior is **undefined** if any of these bits are set
/// to `1`.
#[inline(always)]
pub unsafe fn from_slice_unchecked(bits: &[u64]) -> Self {
EnumSet { __priv_repr: T::Repr::from_u64_slice(bits) }
}
}
//endregion
//region EnumSet iter
/// The iterator used by [`EnumSet`]s.
#[derive(Clone, Debug)]
pub struct EnumSetIter<T: EnumSetType> {
iter: <T::Repr as EnumSetTypeRepr>::Iter,
}
impl<T: EnumSetType> EnumSetIter<T> {
fn new(set: EnumSet<T>) -> EnumSetIter<T> {
EnumSetIter { iter: set.__priv_repr.iter() }
}
}
impl<T: EnumSetType> EnumSet<T> {
/// Iterates the contents of the set in order from the least significant bit to the most
/// significant bit.
///
/// Note that iterator invalidation is impossible as the iterator contains a copy of this type,
/// rather than holding a reference to it.
pub fn iter(&self) -> EnumSetIter<T> {
EnumSetIter::new(*self)
}
}
impl<T: EnumSetType> Iterator for EnumSetIter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|x| unsafe { T::enum_from_u32(x) })
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T: EnumSetType> DoubleEndedIterator for EnumSetIter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.iter
.next_back()
.map(|x| unsafe { T::enum_from_u32(x) })
}
}
impl<T: EnumSetType> ExactSizeIterator for EnumSetIter<T> {}
impl<T: EnumSetType> Extend<T> for EnumSet<T> {
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
iter.into_iter().for_each(|v| {
self.insert(v);
});
}
}
impl<T: EnumSetType> FromIterator<T> for EnumSet<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut set = EnumSet::default();
set.extend(iter);
set
}
}
impl<T: EnumSetType> Extend<EnumSet<T>> for EnumSet<T> {
fn extend<I: IntoIterator<Item = EnumSet<T>>>(&mut self, iter: I) {
iter.into_iter().for_each(|v| {
self.insert_all(v);
});
}
}
impl<T: EnumSetType> FromIterator<EnumSet<T>> for EnumSet<T> {
fn from_iter<I: IntoIterator<Item = EnumSet<T>>>(iter: I) -> Self {
let mut set = EnumSet::default();
set.extend(iter);
set
}
}
impl<T: EnumSetType> IntoIterator for EnumSet<T> {
type Item = T;
type IntoIter = EnumSetIter<T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<T: EnumSetType> Sum for EnumSet<T> {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | v)
}
}
impl<'a, T: EnumSetType> Sum<&'a EnumSet<T>> for EnumSet<T> {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | *v)
}
}
impl<T: EnumSetType> Sum<T> for EnumSet<T> {
fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | v)
}
}
impl<'a, T: EnumSetType> Sum<&'a T> for EnumSet<T> {
fn sum<I: Iterator<Item = &'a T>>(iter: I) -> Self {
iter.fold(EnumSet::empty(), |a, v| a | *v)
}
}
//endregion

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

@ -0,0 +1,62 @@
use crate::repr::EnumSetTypeRepr;
#[cfg(feature = "serde")]
use {crate::EnumSet, serde2 as serde};
/// The trait used to define enum types that may be used with [`EnumSet`].
///
/// This trait must be impelmented using `#[derive(EnumSetType)]`, is not public API, and its
/// internal structure may change at any time with no warning.
///
/// For full documentation on the procedural derive and its options, see
/// [`#[derive(EnumSetType)]`](derive@crate::EnumSetType).
///
/// [`EnumSet`]: crate::set::EnumSet
pub unsafe trait EnumSetType: Copy + Eq + EnumSetTypePrivate {}
/// An [`EnumSetType`] for which [`EnumSet`]s have a guaranteed in-memory representation.
///
/// An implementation of this trait is generated by using
/// [`#[derive(EnumSetType)]`](derive@crate::EnumSetType) with the annotation
/// `#[enumset(repr = "…")]`, where `…` is `u8`, `u16`, `u32`, `u64` or `u128`.
///
/// For any type `T` that implements this trait, the in-memory representation of `EnumSet<T>`
/// is guaranteed to be `Repr`. This guarantee is useful for FFI. See [the `EnumSet` documentation
/// under “FFI, Safety and `repr`”][crate::set::EnumSet#ffi-safety-and-repr] for an example.
///
/// [`EnumSet`]: crate::set::EnumSet
pub unsafe trait EnumSetTypeWithRepr:
EnumSetType + EnumSetTypePrivate<Repr = <Self as EnumSetTypeWithRepr>::Repr>
{
/// The guaranteed representation.
type Repr: EnumSetTypeRepr;
}
/// The actual members of EnumSetType. Put here to avoid polluting global namespaces.
pub unsafe trait EnumSetTypePrivate {
/// The underlying type used to store the bitset.
type Repr: EnumSetTypeRepr;
/// A mask of bits that are valid in the bitset.
const ALL_BITS: Self::Repr;
/// The largest bit used in the bitset.
const BIT_WIDTH: u32;
/// The number of variants in the bitset.
const VARIANT_COUNT: u32;
/// Converts an enum of this type into its bit position.
fn enum_into_u32(self) -> u32;
/// Converts a bit position into an enum value.
unsafe fn enum_from_u32(val: u32) -> Self;
/// Serializes the `EnumSet`.
///
/// This and `deserialize` are part of the `EnumSetType` trait so the procedural derive
/// can control how `EnumSet` is serialized.
#[cfg(feature = "serde")]
fn serialize<S: serde::Serializer>(set: EnumSet<Self>, ser: S) -> Result<S::Ok, S::Error>
where Self: EnumSetType;
/// Deserializes the `EnumSet`.
#[cfg(feature = "serde")]
fn deserialize<'de, D: serde::Deserializer<'de>>(de: D) -> Result<EnumSet<Self>, D::Error>
where Self: EnumSetType;
}

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

@ -0,0 +1,20 @@
#![deny(deprecated)]
use enumset::*;
use serde_derive::*;
#[derive(Serialize, Deserialize, EnumSetType, Debug)]
#[enumset(serialize_as_map)]
#[serde(crate="enumset::__internal::serde")]
pub enum MapEnum {
A, B, C, D, E, F, G, H,
}
#[derive(Serialize, Deserialize, EnumSetType, Debug)]
#[enumset(serialize_as_list)]
#[serde(crate="enumset::__internal::serde")]
pub enum ListEnum {
A, B, C, D, E, F, G, H,
}
fn main() {}

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

@ -0,0 +1,17 @@
error: use of deprecated constant `_::__enumset_derive__generated_warnings::_w`: #[enumset(serialize_as_map)] is deprecated. Use `#[enumset(serialize_repr = "map")]` instead.
--> tests/compile-fail-serde/deprecation.rs:7:11
|
7 | #[enumset(serialize_as_map)]
| ^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> tests/compile-fail-serde/deprecation.rs:1:9
|
1 | #![deny(deprecated)]
| ^^^^^^^^^^
error: use of deprecated constant `_::__enumset_derive__generated_warnings::_w`: #[enumset(serialize_as_list)] is deprecated. Use `#[enumset(serialize_repr = "list")]` instead.
--> tests/compile-fail-serde/deprecation.rs:14:11
|
14 | #[enumset(serialize_as_list)]
| ^^^^^^^^^^^^^^^^^

17
third_party/rust/enumset/tests/compile-fail/explicit_repr.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
use enumset::*;
#[derive(EnumSetType)]
enum OkayEnumButCantUseFromRepr {
Variant,
}
#[derive(EnumSetType)]
#[enumset(repr = "array")]
enum OkayEnumButCantUseFromReprArray {
Variant,
}
fn main() {
EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
EnumSet::<OkayEnumButCantUseFromReprArray>::from_repr([1]);
}

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

@ -0,0 +1,45 @@
error[E0599]: the function or associated item `from_repr` exists for struct `EnumSet<OkayEnumButCantUseFromRepr>`, but its trait bounds were not satisfied
--> tests/compile-fail/explicit_repr.rs:15:44
|
4 | enum OkayEnumButCantUseFromRepr {
| -------------------------------
| |
| doesn't satisfy `<_ as EnumSetTypePrivate>::Repr = <OkayEnumButCantUseFromRepr as EnumSetTypeWithRepr>::Repr`
| doesn't satisfy `OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr`
...
15 | EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
| ^^^^^^^^^ function or associated item cannot be called on `EnumSet<OkayEnumButCantUseFromRepr>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr`
`<OkayEnumButCantUseFromRepr as EnumSetTypePrivate>::Repr = <OkayEnumButCantUseFromRepr as EnumSetTypeWithRepr>::Repr`
which is required by `OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr`
note: the trait `EnumSetTypeWithRepr` must be implemented
--> src/traits.rs
|
| / pub unsafe trait EnumSetTypeWithRepr:
| | EnumSetType + EnumSetTypePrivate<Repr = <Self as EnumSetTypeWithRepr>::Repr>
| |________________________________________________________________________________^
error[E0599]: the function or associated item `from_repr` exists for struct `EnumSet<OkayEnumButCantUseFromReprArray>`, but its trait bounds were not satisfied
--> tests/compile-fail/explicit_repr.rs:16:49
|
10 | enum OkayEnumButCantUseFromReprArray {
| ------------------------------------
| |
| doesn't satisfy `<_ as EnumSetTypePrivate>::Repr = <OkayEnumButCantUseFromReprArray as EnumSetTypeWithRepr>::Repr`
| doesn't satisfy `_: EnumSetTypeWithRepr`
...
16 | EnumSet::<OkayEnumButCantUseFromReprArray>::from_repr([1]);
| ^^^^^^^^^ function or associated item cannot be called on `EnumSet<OkayEnumButCantUseFromReprArray>` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`OkayEnumButCantUseFromReprArray: EnumSetTypeWithRepr`
`<OkayEnumButCantUseFromReprArray as EnumSetTypePrivate>::Repr = <OkayEnumButCantUseFromReprArray as EnumSetTypeWithRepr>::Repr`
which is required by `OkayEnumButCantUseFromReprArray: EnumSetTypeWithRepr`
note: the trait `EnumSetTypeWithRepr` must be implemented
--> src/traits.rs
|
| / pub unsafe trait EnumSetTypeWithRepr:
| | EnumSetType + EnumSetTypePrivate<Repr = <Self as EnumSetTypeWithRepr>::Repr>
| |________________________________________________________________________________^

39
third_party/rust/enumset/tests/compile-fail/syntax.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,39 @@
use enumset::*;
#[derive(EnumSetType)]
#[repr(usize)]
enum BadRepr {
Variant,
}
#[derive(EnumSetType)]
#[repr(usize)]
enum GenericEnum<T> {
Variant,
FieldBlah(T),
}
#[derive(EnumSetType)]
struct BadItemType {
}
#[derive(EnumSetType)]
#[enumset(repr = "u8", repr = "u16")]
enum MultipleReprs {
Variant,
}
#[derive(EnumSetType)]
#[enumset(repr = "abcdef")]
enum InvalidRepr {
Variant,
}
#[derive(EnumSetType)]
#[enumset(serialize_repr = "abcdef")]
enum InvalidSerdeRepr {
Variant,
}
fn main() {}

31
third_party/rust/enumset/tests/compile-fail/syntax.stderr поставляемый Normal file
Просмотреть файл

@ -0,0 +1,31 @@
error: `#[derive(EnumSetType)]` cannot be used on enums with type parameters.
--> tests/compile-fail/syntax.rs:11:17
|
11 | enum GenericEnum<T> {
| ^^^
error: `#[derive(EnumSetType)]` may only be used on enums
--> tests/compile-fail/syntax.rs:17:1
|
17 | / struct BadItemType {
18 | |
19 | | }
| |_^
error: Duplicate field `repr`
--> tests/compile-fail/syntax.rs:22:24
|
22 | #[enumset(repr = "u8", repr = "u16")]
| ^^^^^^^^^^^^
error: `abcdef` is not a valid internal enumset representation.
--> tests/compile-fail/syntax.rs:28:18
|
28 | #[enumset(repr = "abcdef")]
| ^^^^^^^^
error: `abcdef` is not a valid serialized representation.
--> tests/compile-fail/syntax.rs:34:28
|
34 | #[enumset(serialize_repr = "abcdef")]
| ^^^^^^^^

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

@ -1,41 +1,19 @@
use enumset::*;
#[derive(EnumSetType)]
enum VariantOver127 {
Variant = 128,
}
#[derive(EnumSetType)]
#[repr(i64)]
enum VariantOverU32 {
Variant = 0x100000000,
}
#[derive(EnumSetType)]
enum TooManyVariants {
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20,
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39,
_40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58,
_59, _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, _77,
_78, _79, _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, _90, _91, _92, _93, _94, _95, _96,
_97, _98, _99, _100, _101, _102, _103, _104, _105, _106, _107, _108, _109, _110, _111, _112,
_113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
}
#[derive(EnumSetType)]
enum NegativeVariant {
Variant = -1,
}
#[derive(EnumSetType)]
#[repr(usize)]
enum BadRepr {
Variant,
enum HasFields {
Variant(u32),
}
#[derive(EnumSetType)]
enum HasFields {
Variant(u32),
#[enumset(repr = "u128")]
enum BadExplicitRepr {
Variant = 128,
}
#[derive(EnumSetType)]
@ -45,8 +23,8 @@ enum BadSerializationRepr {
}
#[derive(EnumSetType)]
struct BadItemType {
enum NonLiteralRepr {
Variant = 1 + 1,
}
#[derive(EnumSetType)]
@ -56,10 +34,8 @@ enum BadMemRepr {
}
#[derive(EnumSetType)]
enum OkayEnumButCantUseFromRepr {
Variant,
enum ExcessiveReprSize {
Variant = 0xFFFFFFD0,
}
fn main() {
EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
}
fn main() {}

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

@ -1,77 +1,41 @@
error: `#[derive(EnumSetType)]` currently only supports discriminants up to 127.
--> tests/compile-fail/variants.rs:5:5
error: Enum discriminants must not be negative.
--> tests/compile-fail/variants.rs:5:15
|
5 | Variant = 128,
| ^^^^^^^^^^^^^
error: Enum set discriminants must be `u32`s. (larger discrimiants are still unsupported with reprs that allow them.)
--> tests/compile-fail/variants.rs:11:15
|
11 | Variant = 0x100000000,
| ^^^^^^^^^^^
error: `#[derive(EnumSetType)]` currently only supports enums up to 128 variants.
--> tests/compile-fail/variants.rs:22:95
|
22 | _113, _114, _115, _116, _117, _118, _119, _120, _121, _122, _123, _124, _125, _126, _127, _128,
| ^^^^
error: Enum set discriminants must be `u32`s.
--> tests/compile-fail/variants.rs:27:5
|
27 | Variant = -1,
| ^^^^^^^^^^^^
5 | Variant = -1,
| ^^
error: `#[derive(EnumSetType)]` can only be used on fieldless enums.
--> tests/compile-fail/variants.rs:38:5
--> tests/compile-fail/variants.rs:10:5
|
38 | Variant(u32),
10 | Variant(u32),
| ^^^^^^^^^^^^
error: serialize_repr cannot be smaller than bitset.
--> tests/compile-fail/variants.rs:41:10
error: `repr` is too small to contain the largest discriminant.
--> tests/compile-fail/variants.rs:16:5
|
41 | #[derive(EnumSetType)]
| ^^^^^^^^^^^
|
= note: this error originates in the derive macro `EnumSetType` (in Nightly builds, run with -Z macro-backtrace for more info)
16 | Variant = 128,
| ^^^^^^^^^^^^^
error: `#[derive(EnumSetType)]` may only be used on enums
--> tests/compile-fail/variants.rs:48:1
error: `serialize_repr` is too small to contain the largest discriminant.
--> tests/compile-fail/variants.rs:22:5
|
48 | / struct BadItemType {
49 | |
50 | | }
| |_^
22 | Variant = 8,
| ^^^^^^^^^^^
error: repr cannot be smaller than bitset.
--> tests/compile-fail/variants.rs:52:10
error: Enum discriminants must be literal expressions.
--> tests/compile-fail/variants.rs:27:5
|
52 | #[derive(EnumSetType)]
| ^^^^^^^^^^^
|
= note: this error originates in the derive macro `EnumSetType` (in Nightly builds, run with -Z macro-backtrace for more info)
27 | Variant = 1 + 1,
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr` is not satisfied
--> tests/compile-fail/variants.rs:64:5
|
64 | EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `EnumSetTypeWithRepr` is not implemented for `OkayEnumButCantUseFromRepr`
|
note: required by a bound in `enumset::EnumSet::<T>::from_repr`
--> src/lib.rs
|
| where T: EnumSetTypeWithRepr {
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `enumset::EnumSet::<T>::from_repr`
error[E0277]: the trait bound `OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr` is not satisfied
--> tests/compile-fail/variants.rs:64:5
error: `repr` is too small to contain the largest discriminant.
--> tests/compile-fail/variants.rs:33:5
|
64 | EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `EnumSetTypeWithRepr` is not implemented for `OkayEnumButCantUseFromRepr`
33 | Variant = 16,
| ^^^^^^^^^^^^
error[E0277]: the trait bound `OkayEnumButCantUseFromRepr: EnumSetTypeWithRepr` is not satisfied
--> tests/compile-fail/variants.rs:64:54
error: Maximum discriminant allowed is `0xFFFFFFBF`.
--> tests/compile-fail/variants.rs:38:5
|
64 | EnumSet::<OkayEnumButCantUseFromRepr>::from_repr(1);
| ^ the trait `EnumSetTypeWithRepr` is not implemented for `OkayEnumButCantUseFromRepr`
38 | Variant = 0xFFFFFFD0,
| ^^^^^^^^^^^^^^^^^^^^

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

@ -0,0 +1,360 @@
use enumset::*;
macro_rules! read_slice {
($set:expr, $size:expr) => {{
let mut arr = [0; $size];
$set.copy_into_slice(&mut arr);
arr
}};
}
macro_rules! try_read_slice {
($set:expr, $size:expr) => {{
let mut arr = [0; $size];
match $set.try_copy_into_slice(&mut arr) {
Some(()) => Some(arr),
None => None,
}
}};
}
macro_rules! read_slice_truncated {
($set:expr, $size:expr) => {{
let mut arr = [0; $size];
$set.copy_into_slice_truncated(&mut arr);
arr
}};
}
#[derive(EnumSetType, Debug)]
pub enum Enum8 {
A, B, C, D, E, F, G,
// H omitted for non-existent bit test
}
#[derive(EnumSetType, Debug)]
pub enum Enum16 {
A, B, C, D, E=8, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum Enum32 {
A, B, C, D, E=16, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum Enum64 {
A, B, C, D, E=32, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum Enum128 {
A, B, C, D, E=64, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum Enum192 {
A, B, C, D, E=128, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum Enum256 {
A, B, C, D, E=192, F, G, H,
}
macro_rules! check_simple_conversion {
($mod:ident, $e:ident) => {
mod $mod {
use super::*;
#[test]
fn to_integer() {
assert_eq!(7,
($e::A | $e::B | $e::C).as_u8());
assert_eq!(7,
($e::A | $e::B | $e::C).as_u16());
assert_eq!(7,
($e::A | $e::B | $e::C).as_u32());
assert_eq!(7,
($e::A | $e::B | $e::C).as_u64());
assert_eq!(7,
($e::A | $e::B | $e::C).as_u128());
assert_eq!(7,
($e::A | $e::B | $e::C).as_usize());
}
#[test]
fn try_from_integer() {
assert_eq!(Some($e::A | $e::B | $e::C),
EnumSet::try_from_u8(7));
assert_eq!(None,
EnumSet::<$e>::try_from_u8(7 | (1 << 7)));
assert_eq!(None,
EnumSet::<$e>::try_from_u16(7 | (1 << 15)));
assert_eq!(None,
EnumSet::<$e>::try_from_u32(7 | (1 << 31)));
assert_eq!(None,
EnumSet::<$e>::try_from_usize(7 | (1 << 31)));
assert_eq!(None,
EnumSet::<$e>::try_from_u64(7 | (1 << 63)));
assert_eq!(None,
EnumSet::<$e>::try_from_u128(7 | (1 << 127)));
}
#[test]
fn from_integer_truncated() {
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u8_truncated(7));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u8_truncated(7 | (1 << 7)));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u16_truncated(7 | (1 << 15)));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u32_truncated(7 | (1 << 31)));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_usize_truncated(7 | (1 << 31)));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u64_truncated(7 | (1 << 63)));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::from_u128_truncated(7 | (1 << 127)));
}
#[test]
fn basic_to_array() {
// array tests
assert_eq!(($e::A | $e::B | $e::C).as_array_truncated(),
[]);
assert_eq!(EnumSet::<$e>::EMPTY.as_array_truncated(),
[]);
assert_eq!(($e::A | $e::B | $e::C).as_array(),
[7]);
assert_eq!(($e::A | $e::B | $e::C).as_array(),
[7, 0]);
assert_eq!(($e::A | $e::B | $e::C).as_array(),
[7, 0, 0]);
assert_eq!(($e::A | $e::B | $e::C).as_array(),
[7, 0, 0, 0]);
assert_eq!(($e::A | $e::B | $e::C).as_array(),
[7, 0, 0, 0, 0]);
// slice tests
assert_eq!(read_slice!($e::A | $e::B | $e::C, 1),
[7]);
assert_eq!(read_slice!($e::A | $e::B | $e::C, 2),
[7, 0]);
assert_eq!(read_slice!($e::A | $e::B | $e::C, 3),
[7, 0, 0]);
assert_eq!(read_slice!($e::A | $e::B | $e::C, 4),
[7, 0, 0, 0]);
assert_eq!(read_slice!($e::A | $e::B | $e::C, 5),
[7, 0, 0, 0, 0]);
// slice tests truncated
assert_eq!(read_slice_truncated!($e::A | $e::B | $e::C, 1),
[7]);
assert_eq!(read_slice_truncated!($e::A | $e::B | $e::C, 2),
[7, 0]);
assert_eq!(read_slice_truncated!($e::A | $e::B | $e::C, 3),
[7, 0, 0]);
assert_eq!(read_slice_truncated!($e::A | $e::B | $e::C, 4),
[7, 0, 0, 0]);
assert_eq!(read_slice_truncated!($e::A | $e::B | $e::C, 5),
[7, 0, 0, 0, 0]);
}
#[test]
fn basic_from_array() {
// array tests
assert_eq!(EnumSet::<$e>::EMPTY,
EnumSet::<$e>::from_array([]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array([7]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array([7, 0, 0]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array([7, 0, 0, 0]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array([7, 0, 0, 0, 0]));
// array tests
assert_eq!(EnumSet::<$e>::EMPTY,
EnumSet::<$e>::from_slice(&[]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice(&[7]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice(&[7, 0, 0]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice(&[7, 0, 0, 0]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice(&[7, 0, 0, 0, 0]));
}
#[test]
fn basic_from_array_truncated() {
// array tests
assert_eq!(EnumSet::<$e>::EMPTY,
EnumSet::<$e>::from_array_truncated([]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array_truncated([7 | (1 << 31)]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array_truncated([7, 0, 16]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array_truncated([7, 0, 0, 16]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_array_truncated([7, 0, 0, 0, 16]));
// array tests
assert_eq!(EnumSet::<$e>::EMPTY,
EnumSet::<$e>::from_slice_truncated(&[]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice_truncated(&[7 | (1 << 31)]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice_truncated(&[7, 0, 16]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice_truncated(&[7, 0, 0, 16]));
assert_eq!($e::A | $e::B | $e::C,
EnumSet::<$e>::from_slice_truncated(&[7, 0, 0, 0, 16]));
}
#[test]
#[should_panic]
fn fail_from_u8() {
EnumSet::<$e>::from_u8(7 | (1 << 7));
}
#[test]
#[should_panic]
fn fail_from_u16() {
EnumSet::<$e>::from_u16(7 | (1 << 15));
}
#[test]
#[should_panic]
fn fail_from_u32() {
EnumSet::<$e>::from_u32(7 | (1 << 31));
}
#[test]
#[should_panic]
fn fail_from_usize() {
EnumSet::<$e>::from_usize(7 | (1 << 31));
}
#[test]
#[should_panic]
fn fail_from_u64() {
EnumSet::<$e>::from_u64(7 | (1 << 63));
}
#[test]
#[should_panic]
fn fail_from_u128() {
EnumSet::<$e>::from_u128(7 | (1 << 127));
}
#[test]
#[should_panic]
fn fail_to_array() {
($e::A | $e::B | $e::C).as_array::<0>();
}
#[test]
#[should_panic]
fn fail_to_slice() {
read_slice!($e::A | $e::B | $e::C, 0);
}
#[test]
#[should_panic]
fn fail_from_array_1() {
EnumSet::<$e>::from_array([7 | (1 << 63), 0, 0, 0]);
}
#[test]
#[should_panic]
fn fail_from_slice_1() {
EnumSet::<$e>::from_slice(&[7 | (1 << 63), 0, 0, 0]);
}
#[test]
#[should_panic]
fn fail_from_array_2() {
EnumSet::<$e>::from_array([7, 0, 0, 0, 1]);
}
#[test]
#[should_panic]
fn fail_from_slice_2() {
EnumSet::<$e>::from_slice(&[7, 0, 0, 0, 1]);
}
}
};
}
check_simple_conversion!(enum_8_simple, Enum8);
check_simple_conversion!(enum_16_simple, Enum16);
check_simple_conversion!(enum_32_simple, Enum32);
check_simple_conversion!(enum_64_simple, Enum64);
check_simple_conversion!(enum_128_simple, Enum128);
check_simple_conversion!(enum_192_simple, Enum192);
check_simple_conversion!(enum_256_simple, Enum256);
macro_rules! check_oversized_64 {
($mod:ident, $e:ident) => {
mod $mod {
use super::*;
#[test]
fn downcast_to_u64() {
assert_eq!(Some(7), ($e::A | $e::B | $e::C).try_as_u64());
assert_eq!(Some([7]), ($e::A | $e::B | $e::C).try_as_array());
assert_eq!(Some([7]), try_read_slice!($e::A | $e::B | $e::C, 1));
assert_eq!(None, ($e::E | $e::F | $e::G).try_as_u64());
assert_eq!(None, ($e::E | $e::F | $e::G).try_as_array::<1>());
assert_eq!(None, try_read_slice!($e::E | $e::F | $e::G, 1));
}
#[test]
fn downcast_to_u64_truncated() {
assert_eq!(0, ($e::E | $e::F | $e::G).as_u64_truncated());
assert_eq!([0], ($e::E | $e::F | $e::G).as_array_truncated());
assert_eq!([0], read_slice_truncated!($e::E | $e::F | $e::G, 1));
}
#[test]
#[should_panic]
fn fail_to_u64() {
($e::E | $e::F | $e::G).as_u64();
}
}
};
}
check_oversized_64!(enum_128_oversized_64, Enum128);
check_oversized_64!(enum_192_oversized_64, Enum192);
check_oversized_64!(enum_256_oversized_64, Enum256);
macro_rules! check_oversized_128 {
($mod:ident, $e:ident) => {
mod $mod {
use super::*;
#[test]
fn downcast_to_u128() {
assert_eq!(Some(7), ($e::A | $e::B | $e::C).try_as_u128());
assert_eq!(None, ($e::E | $e::F | $e::G).try_as_u128());
assert_eq!(0, ($e::E | $e::F | $e::G).as_u128_truncated());
}
#[test]
#[should_panic]
fn fail_to_u128() {
($e::E | $e::F | $e::G).as_u128();
}
}
};
}
check_oversized_128!(enum_192_oversized_128, Enum192);
check_oversized_128!(enum_256_oversized_128, Enum256);

88
third_party/rust/enumset/tests/ops.rs поставляемый
Просмотреть файл

@ -21,6 +21,7 @@ pub enum SmallEnumExplicitDerive {
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
}
#[derive(EnumSetType, Debug)]
#[enumset(repr = "u128")]
pub enum LargeEnum {
_00, _01, _02, _03, _04, _05, _06, _07,
_10, _11, _12, _13, _14, _15, _16, _17,
@ -73,6 +74,30 @@ pub enum ReprEnum3 {
pub enum ReprEnum4 {
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
}
#[derive(EnumSetType, Debug)]
pub enum GiantEnum {
A = 100, B = 200, C = 300, D = 400, E = 500, F = 600, G = 700, H = 800,
}
#[derive(EnumSetType, Debug)]
#[enumset(repr = "array")]
pub enum SmallArrayEnum {
A, B, C, D, E, F, G, H
}
#[derive(EnumSetType, Debug)]
#[enumset(repr = "array")]
pub enum MarginalArrayEnumS2 {
A, B, C, D, E, F, G, H, Marginal = 64,
}
#[derive(EnumSetType, Debug)]
#[enumset(repr = "array")]
pub enum MarginalArrayEnumS2H {
A = 64, B, C, D, E, F, G, H, Marginal = 127,
}
#[derive(EnumSetType, Debug)]
#[enumset(repr = "array")]
pub enum MarginalArrayEnumS3 {
A, B, C, D, E, F, G, H, Marginal = 128,
}
macro_rules! test_variants {
($enum_name:ident $all_empty_test:ident $($variant:ident,)*) => {
@ -113,7 +138,7 @@ macro_rules! test_enum {
($e:ident, $mem_size:expr) => {
const CONST_SET: EnumSet<$e> = enum_set!($e::A | $e::C);
const CONST_1_SET: EnumSet<$e> = enum_set!($e::A);
const EMPTY_SET: EnumSet<$e> = enum_set!();
const EMPTY_SET: EnumSet<$e> = EnumSet::EMPTY;
#[test]
fn const_set() {
assert_eq!(CONST_SET.len(), 2);
@ -201,6 +226,13 @@ macro_rules! test_enum {
assert_eq!(set, set_5);
}
#[test]
fn empty_iter_test() {
for _ in EnumSet::<$e>::new() {
panic!("should not happen");
}
}
#[test]
fn iter_ordering_test() {
let set_a = $e::A | $e::B | $e::E;
@ -218,17 +250,34 @@ macro_rules! test_enum {
fn check_iter_size_hint(set: EnumSet<$e>) {
let count = set.len();
let mut itr = set.iter();
for idx in 0 .. count {
assert_eq!(itr.size_hint(), (count-idx, Some(count-idx)));
assert_eq!(itr.len(), count-idx);
assert!(itr.next().is_some());
// check for forward iteration
{
let mut itr = set.iter();
for idx in 0 .. count {
assert_eq!(itr.size_hint(), (count-idx, Some(count-idx)));
assert_eq!(itr.len(), count-idx);
assert!(itr.next().is_some());
}
assert_eq!(itr.size_hint(), (0, Some(0)));
assert_eq!(itr.len(), 0);
}
// check for backwards iteration
{
let mut itr = set.iter().rev();
for idx in 0 .. count {
assert_eq!(itr.size_hint(), (count-idx, Some(count-idx)));
assert_eq!(itr.len(), count-idx);
assert!(itr.next().is_some());
}
assert_eq!(itr.size_hint(), (0, Some(0)));
assert_eq!(itr.len(), 0);
}
assert_eq!(itr.size_hint(), (0, Some(0)));
assert_eq!(itr.len(), 0);
}
#[test]
fn test_iter_size_hint() {
check_iter_size_hint(EnumSet::<$e>::new());
check_iter_size_hint(EnumSet::<$e>::all());
let mut set = EnumSet::new();
set.insert($e::A);
@ -283,7 +332,21 @@ macro_rules! test_enum {
#[test]
fn to_from_bits() {
let value = $e::A | $e::C | $e::D | $e::F | $e::E | $e::G;
assert_eq!(EnumSet::from_u128(value.as_u128()), value);
if EnumSet::<$e>::bit_width() < 128 {
assert_eq!(EnumSet::from_u128(value.as_u128()), value);
}
if EnumSet::<$e>::bit_width() < 64 {
assert_eq!(EnumSet::from_u64(value.as_u64()), value);
}
if EnumSet::<$e>::bit_width() < 32 {
assert_eq!(EnumSet::from_u32(value.as_u32()), value);
}
if EnumSet::<$e>::bit_width() < 16 {
assert_eq!(EnumSet::from_u16(value.as_u16()), value);
}
if EnumSet::<$e>::bit_width() < 8 {
assert_eq!(EnumSet::from_u8(value.as_u8()), value);
}
}
#[test]
@ -385,6 +448,11 @@ tests!(repr_enum_u32, test_enum!(ReprEnum, 4));
tests!(repr_enum_u64, test_enum!(ReprEnum2, 4));
tests!(repr_enum_isize, test_enum!(ReprEnum3, 4));
tests!(repr_enum_c, test_enum!(ReprEnum4, 4));
tests!(giant_enum, test_enum!(GiantEnum, 104));
tests!(small_array_enum, test_enum!(SmallArrayEnum, 8));
tests!(marginal_array_enum_s2, test_enum!(MarginalArrayEnumS2, 16));
tests!(marginal_array_enum_s2h, test_enum!(MarginalArrayEnumS2H, 16));
tests!(marginal_array_enum_s3, test_enum!(MarginalArrayEnumS3, 24));
#[derive(EnumSetType, Debug)]
pub enum ThresholdEnum {
@ -457,6 +525,6 @@ bits_tests!(test_u64_bits, U64, (U128), u64,
as_u64 try_as_u64 as_u64_truncated from_u64 try_from_u64 from_u64_truncated);
bits_tests!(test_u128_bits, U128, (), u128,
as_u128 try_as_u128 as_u128_truncated from_u128 try_from_u128 from_u128_truncated);
bits_tests!(test_uize_bits, U32, (U128), usize,
bits_tests!(test_usize_bits, U32, (U128), usize,
as_usize try_as_usize as_usize_truncated
from_usize try_from_usize from_usize_truncated);

71
third_party/rust/enumset/tests/serde.rs поставляемый
Просмотреть файл

@ -10,12 +10,30 @@ type None = ();
type Result = ();
#[derive(Serialize, Deserialize, EnumSetType, Debug)]
#[enumset(serialize_as_list)]
#[enumset(serialize_repr = "list")]
#[serde(crate="serde2")]
pub enum ListEnum {
A, B, C, D, E, F, G, H,
}
#[derive(Serialize, Deserialize, EnumSetType, Debug)]
#[enumset(serialize_repr = "map")]
#[serde(crate="serde2")]
pub enum MapEnum {
A, B, C, D, E, F, G, H,
}
#[derive(EnumSetType, Debug)]
#[enumset(serialize_repr = "array")]
pub enum ArrayEnum {
A, B, C, D, E, F, G, H,
}
#[derive(EnumSetType, Debug)]
pub enum LargeEnum {
A, B, C, D, E=200, F, G, H,
}
#[derive(EnumSetType, Debug)]
#[enumset(serialize_repr = "u128")]
pub enum ReprEnum {
@ -30,23 +48,37 @@ pub enum DenyUnknownEnum {
macro_rules! serde_test_simple {
($e:ident, $ser_size:expr) => {
const VALUES: &[EnumSet<$e>] = &[
enum_set!(),
enum_set!($e::A | $e::C | $e::D | $e::F | $e::E | $e::G),
enum_set!($e::A),
enum_set!($e::H),
enum_set!($e::A | $e::B),
enum_set!($e::A | $e::B | $e::C | $e::D),
enum_set!($e::A | $e::B | $e::C | $e::D | $e::F | $e::G | $e::H),
enum_set!($e::G | $e::H),
enum_set!($e::E | $e::F | $e::G | $e::H),
];
#[test]
fn serialize_deserialize_test_bincode() {
let value = $e::A | $e::C | $e::D | $e::F | $e::E | $e::G;
let serialized = bincode::serialize(&value).unwrap();
let deserialized = bincode::deserialize::<EnumSet<$e>>(&serialized).unwrap();
assert_eq!(value, deserialized);
if $ser_size != !0 {
assert_eq!(serialized.len(), $ser_size);
for &value in VALUES {
let serialized = bincode::serialize(&value).unwrap();
let deserialized = bincode::deserialize::<EnumSet<$e>>(&serialized).unwrap();
assert_eq!(value, deserialized);
if $ser_size != !0 {
assert_eq!(serialized.len(), $ser_size);
}
}
}
#[test]
fn serialize_deserialize_test_json() {
let value = $e::A | $e::C | $e::D | $e::F | $e::E | $e::G;
let serialized = serde_json::to_string(&value).unwrap();
let deserialized = serde_json::from_str::<EnumSet<$e>>(&serialized).unwrap();
assert_eq!(value, deserialized);
for &value in VALUES {
let serialized = serde_json::to_string(&value).unwrap();
let deserialized = serde_json::from_str::<EnumSet<$e>>(&serialized).unwrap();
assert_eq!(value, deserialized);
}
}
}
}
@ -74,17 +106,32 @@ fn test_deny_unknown() {
}
#[test]
fn test_json_reprs() {
fn test_json_reprs_basic() {
assert_eq!(ListEnum::A | ListEnum::C | ListEnum::F,
serde_json::from_str::<EnumSet<ListEnum>>(r#"["A","C","F"]"#).unwrap());
assert_eq!(MapEnum::A | MapEnum::C | MapEnum::F,
serde_json::from_str::<EnumSet<MapEnum>>(r#"{"A":true,"C":true,"F":true}"#).unwrap());
assert_eq!(ReprEnum::A | ReprEnum::C | ReprEnum::D,
serde_json::from_str::<EnumSet<ReprEnum>>("13").unwrap());
assert_eq!(r#"["A","C","F"]"#,
serde_json::to_string(&(ListEnum::A | ListEnum::C | ListEnum::F)).unwrap());
assert_eq!(r#"{"A":true,"C":true,"F":true}"#,
serde_json::to_string(&(MapEnum::A | MapEnum::C | MapEnum::F)).unwrap());
assert_eq!("13",
serde_json::to_string(&(ReprEnum::A | ReprEnum::C | ReprEnum::D)).unwrap());
}
#[test]
fn test_json_reprs_edge_cases() {
assert_eq!(MapEnum::A | MapEnum::C | MapEnum::F,
serde_json::from_str::<EnumSet<MapEnum>>(r#"{"D":false,"A":true,"E":false,"C":true,"F":true}"#).unwrap());
assert_eq!(LargeEnum::A | LargeEnum::B | LargeEnum::C | LargeEnum::D,
serde_json::from_str::<EnumSet<LargeEnum>>(r#"[15]"#).unwrap());
}
tests!(list_enum, serde_test_simple!(ListEnum, !0));
tests!(map_enum, serde_test_simple!(MapEnum, !0));
tests!(array_enum, serde_test_simple!(ArrayEnum, !0));
tests!(large_enum, serde_test_simple!(LargeEnum, !0));
tests!(repr_enum, serde_test!(ReprEnum, 16));
tests!(deny_unknown_enum, serde_test_simple!(DenyUnknownEnum, 16));

4
third_party/rust/enumset/tests/trybuild.rs поставляемый
Просмотреть файл

@ -2,6 +2,10 @@
#[test]
fn ui() {
let t = trybuild::TestCases::new();
t.compile_fail("tests/compile-fail/*.rs");
t.pass("tests/compile-pass/*.rs");
#[cfg(feature = "serde")]
t.compile_fail("tests/compile-fail-serde/*.rs");
}

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

@ -1 +1 @@
{"files":{"Cargo.toml":"2de22e952501bb15d5b13fef8ead3f53d6a40af1c1a284d332bb4a090ba59a3c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"79b4502d93c23afe2765054a80d03716d4934eb260cdfbe8c401898df3aa5a8f","README.md":"d45f82ad73b39aad91f85d0688bc6a94402293c40c295d0cab7b2a9b7225677b","src/lib.rs":"149dbabe0beb802bb41a560cd03f95c4992600ac07fdf57a3b1610a557bc10f4"},"package":"03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0"}
{"files":{"Cargo.toml":"b22d675f79e7c888bd013b3beff0335cdfde340351dd2c46b9b2fd55156d0fac","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7405fdff2ff8682a5384da664436b9b2aca47557572513f5b27686a5347f9b8e","README.md":"d45f82ad73b39aad91f85d0688bc6a94402293c40c295d0cab7b2a9b7225677b","src/lib.rs":"ad2d7adf74ded236b268e4c3ba9e18260527323d1f030c7a4c39fdb550c0634a"},"package":"e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af"}

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

@ -10,21 +10,22 @@
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
edition = "2021"
name = "enumset_derive"
version = "0.6.1"
version = "0.8.1"
authors = ["Alissa Rao <lymia@lymiahugs.com>"]
description = "An internal helper crate for enumset. Not public API."
documentation = "https://lymia.moe/doc/enumset/enumset/"
readme = "README.md"
license = "MIT/Apache-2.0"
repository = "https://github.com/Lymia/enumset"
resolver = "1"
[lib]
proc-macro = true
[dependencies.darling]
version = "0.14"
version = "0.20"
default-features = false
[dependencies.proc-macro-crate]
@ -38,7 +39,7 @@ version = "1"
version = "1"
[dependencies.syn]
version = "1"
version = "2"
[features]
serde = []

2
third_party/rust/enumset_derive/LICENSE-MIT поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
Copyright (c) 2017-2020 Alissa Rao <lymiahugs@gmail.com>
Copyright (c) 2017-2023 Alissa Rao <lymiahugs@gmail.com>
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

810
third_party/rust/enumset_derive/src/lib.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

@ -7,6 +7,353 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
## [3.0.0] - 2023-05-01
This breaking release should not impact most users.
It only affects custom character sets used for base64 of which there are no instances of on GitHub.
### Changed
* Upgrade base64 to v0.21 (#543)
Thanks to @jeff-hiner for submitting the PR.
Remove support for custom character sets.
This is technically a breaking change.
A code search on GitHub revealed no instances of anyone using that, and `serde_with` ships with many predefined character sets.
The removal means that future base64 upgrade will no longer be breaking changes.
## [2.3.3] - 2023-04-27
### Changed
* Update `syn` to v2 and `darling` to v0.20 (#578)
Update proc-macro dependencies.
This change should have no impact on users, but now uses the same dependency as `serde_derive`.
## [2.3.2] - 2023-04-05
### Changed
* Improve the error message when deserializing `OneOrMany` or `PickFirst` fails.
It now includes the original error message for each of the individual variants.
This is possible by dropping untagged enums as the internal implementations, since they will likely never support this, as these old PRs show [serde#2376](https://github.com/serde-rs/serde/pull/2376) and [serde#1544](https://github.com/serde-rs/serde/pull/1544).
The new errors look like:
```text
OneOrMany could not deserialize any variant:
One: invalid type: map, expected u32
Many: invalid type: map, expected a sequence
```
```text
PickFirst could not deserialize any variant:
First: invalid type: string "Abc", expected u32
Second: invalid digit found in string
```
### Fixed
* Specify the correct minimum serde version as dependency. (#588)
Thanks to @nox for submitting a PR.
## [2.3.1] - 2023-03-10
### Fixed
* Undo the changes to the trait bound for `Seq`. (#570, #571)
The new implementation caused issues with serialization formats that require the sequence length beforehand.
It also caused problems, that certain attributes which worked before no longer worked, due to mismatching number of references.
Thanks to @stefunctional for reporting and for @stephaneyfx for providing a test case.
## [2.3.0] - 2023-03-09
### Added
* Add `serde_as` compatible versions for the existing duplicate key and value handling. (#534)
The new types `MapPreventDuplicates`, `MapFirstKeyWins`, `SetPreventDuplicates`, and `SetLastValueWins` can replace the existing modules `maps_duplicate_key_is_error`, `maps_first_key_wins`, `sets_duplicate_value_is_error`, and `sets_last_value_wins`.
* Added a new `KeyValueMap` type using the map key as a struct field. (#341)
This conversion is useful for maps, where an ID value is the map key, but the ID should become part of a single struct.
The conversion allows this, by using a special field named `$key$`.
This conversion is possible for structs and maps, using the `$key$` field.
Tuples, tuple structs, and sequences are supported by turning the first value into the map key.
Each of the `SimpleStruct`s
```rust
// Somewhere there is a collection:
// #[serde_as(as = "KeyValueMap<_>")]
// Vec<SimpleStruct>,
#[derive(Serialize, Deserialize)]
struct SimpleStruct {
b: bool,
// The field named `$key$` will become the map key
#[serde(rename = "$key$")]
id: String,
i: i32,
}
```
will turn into a JSON snippet like this.
```json
"id-0000": {
"b": false,
"i": 123
},
```
### Changed
* Relax the trait bounds of `Seq` to allow for more custom types. (#565)
This extends the support beyond tuples.
### Fixed
* `EnumMap` passes the `human_readable` status of the `Serializer` to more places.
* Support `alloc` on targets without `target_has_atomic = "ptr"`. (#560)
Thanks to @vembacher for reporting and fixing the issue.
## [2.2.0] - 2023-01-09
### Added
* Add new `Map` and `Seq` types for converting between maps and tuple lists. (#527)
The behavior is not new, but already present using `BTreeMap`/`HashMap` or `Vec`.
However, the new types `Map` and `Seq` are also available on `no_std`, even without the `alloc` feature.
### Changed
* Pin the `serde_with_macros` dependency to the same version as the main crate.
This simplifies publishing and ensures that always a compatible version is picked.
### Fixed
* `serde_with::apply` had an issue matching types when invisible token groups where in use (#538)
The token groups can stem from macro_rules expansion, but should be treated mostly transparent.
The old code required a group to match a group, while now groups are silently removed when checking for type patterns.
## [2.1.0] - 2022-11-16
### Added
* Add new `apply` attribute to simplify repetitive attributes over many fields.
Multiple rules and multiple attributes can be provided each.
```rust
#[serde_with::apply(
Option => #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")],
Option<bool> => #[serde(rename = "bool")],
)]
#[derive(serde::Serialize)]
struct Data {
a: Option<String>,
b: Option<u64>,
c: Option<String>,
d: Option<bool>,
}
```
The `apply` attribute will expand into this, applying the attributs to the matching fields:
```rust
#[derive(serde::Serialize)]
struct Data {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
a: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
b: Option<u64>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
c: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "bool")]
d: Option<bool>,
}
```
The attribute supports field matching using many rules, such as `_` to apply to all fields and partial generics like `Option` to match any `Option` be it `Option<String>`, `Option<bool>`, or `Option<T>`.
### Fixed
* The derive macros `SerializeDisplay` and `DeserializeFromStr` now take better care not to use conflicting names for generic values. (#526)
All used generics now start with `__` to make conflicts with manually written code unlikely.
Thanks to @Elrendio for submitting a PR fixing the issue.
## [2.0.1] - 2022-09-09
### Added
* `time` added support for the well-known `Iso8601` format.
This extends the existing support of `Rfc2822` and `Rfc3339`.
### Changed
* Warn if `serde_as` is used on an enum variant.
Attributes on enum variants were never supported.
But `#[serde(with = "...")]` can be added on variants, such that some confusion can occur when migration ([#499](https://github.com/jonasbb/serde_with/issues/499)).
### Note
A cargo bug ([cargo#10801](https://github.com/rust-lang/cargo/issues/10801)) means that upgrading from v1 to v2 may add unnecessary crates to the `Cargo.lock` file.
A diff of the lock-file makes it seem that `serde_with` depends on new crates, even though these crates are unused and will not get compiled or linked.
However, tools consuming `Cargo.lock` or `cargo metadata` might give wrong results.
## [2.0.0] - 2022-07-17
### Added
* Make `JsonString<T>` smarter by allowing nesting `serde_as` definitions.
This allows applying custom serialization logic, before the value gets converted into a JSON string.
```rust
// Rust
#[serde_as(as = "JsonString<Vec<(JsonString, _)>>")]
value: BTreeMap<[u8; 2], u32>,
// JSON
{"value":"[[\"[1,2]\",3],[\"[4,5]\",6]]"}
```
### Changed
* Make `#[serde_as]` behave more intuitive on `Option<T>` fields.
The `#[serde_as]` macro now detects if a `#[serde_as(as = "Option<S>")]` is used on a field of type `Option<T>` and applies `#[serde(default)]` to the field.
This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.
The `Option` field and transformation are detected by directly matching on the type name.
These variants are detected as `Option`.
* `Option`
* `std::option::Option`, with or without leading `::`
* `core::option::Option`, with or without leading `::`
If an existing `default` attribute is detected, the attribute is not applied again.
This behavior can be suppressed by using `#[serde_as(no_default)]` or `#[serde_as(as = "Option<S>", no_default)]`.
* `NoneAsEmptyString` and `string_empty_as_none` use a different serialization bound (#388).
Both types used `AsRef<str>` as the serialization bound.
This is limiting for non-string types like `Option<i32>`.
The deserialization often was already more flexible, due to the `FromStr` bound.
For most std types this should have little impact, as the types implementing `AsRef<str>` mostly implement `Display`, too, such as `String`, `Cow<str>`, or `Rc<str>`.
* Bump MSRV to 1.60. This is required for the optional dependency feature syntax in cargo.
### Removed
* Remove old module based conversions.
The newer `serde_as` based conversions are preferred.
* `seq_display_fromstr`: Use `DisplayFromStr` in combination with your container type:
```rust
#[serde_as(as = "BTreeSet<DisplayFromStr>")]
addresses: BTreeSet<Ipv4Addr>,
#[serde_as(as = "Vec<DisplayFromStr>")]
bools: Vec<bool>,
```
* `tuple_list_as_map`: Use `BTreeMap` on a `Vec` of tuples:
```rust
#[serde_as(as = "BTreeMap<_, _>")] // HashMap will also work
s: Vec<(i32, String)>,
```
* `map_as_tuple_list` can be replaced with `#[serde_as(as = "Vec<(_, _)>")]`.
* `display_fromstr` can be replaced with `#[serde_as(as = "DisplayFromStr")]`.
* `bytes_or_string` can be replaced with `#[serde_as(as = "BytesOrString")]`.
* `default_on_error` can be replaced with `#[serde_as(as = "DefaultOnError")]`.
* `default_on_null` can be replaced with `#[serde_as(as = "DefaultOnNull")]`.
* `string_empty_as_none` can be replaced with `#[serde_as(as = "NoneAsEmptyString")]`.
* `StringWithSeparator` can now only be used in `serde_as`.
The definition of the `Separator` trait and its implementations have been moved to the `formats` module.
* `json::nested` can be replaced with `#[serde_as(as = "json::JsonString")]`.
* Remove previously deprecated modules.
* `sets_first_value_wins`
* `btreemap_as_tuple_list` and `hashmap_as_tuple_list` can be replaced with `#[serde_as(as = "Vec<(_, _)>")]`.
### Note
A cargo bug ([cargo#10801](https://github.com/rust-lang/cargo/issues/10801)) means that upgrading from v1 to v2 may add unnecessary crates to the `Cargo.lock` file.
A diff of the lock-file makes it seem that `serde_with` depends on new crates, even though these crates are unused and will not get compiled or linked.
## [2.0.0-rc.0] - 2022-06-29
### Changed
* Make `#[serde_as]` behave more intuitive on `Option<T>` fields.
The `#[serde_as]` macro now detects if a `#[serde_as(as = "Option<S>")]` is used on a field of type `Option<T>` and applies `#[serde(default)]` to the field.
This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.
The `Option` field and transformation are detected by directly matching on the type name.
These variants are detected as `Option`.
* `Option`
* `std::option::Option`, with or without leading `::`
* `core::option::Option`, with or without leading `::`
If an existing `default` attribute is detected, the attribute is not applied again.
This behavior can be suppressed by using `#[serde_as(no_default)]` or `#[serde_as(as = "Option<S>", no_default)]`.
* `NoneAsEmptyString` and `string_empty_as_none` use a different serialization bound (#388).
Both types used `AsRef<str>` as the serialization bound.
This is limiting for non-string types like `Option<i32>`.
The deserialization often was already more flexible, due to the `FromStr` bound.
For most std types this should have little impact, as the types implementing `AsRef<str>` mostly implement `Display`, too, such as `String`, `Cow<str>`, or `Rc<str>`.
* Bump MSRV to 1.60. This is required for the optional dependency feature syntax in cargo.
### Removed
* Remove old module based conversions.
The newer `serde_as` based conversions are preferred.
* `seq_display_fromstr`: Use `DisplayFromStr` in combination with your container type:
```rust
#[serde_as(as = "BTreeSet<DisplayFromStr>")]
addresses: BTreeSet<Ipv4Addr>,
#[serde_as(as = "Vec<DisplayFromStr>")]
bools: Vec<bool>,
```
* `tuple_list_as_map`: Use `BTreeMap` on a `Vec` of tuples:
```rust
#[serde_as(as = "BTreeMap<_, _>")] // HashMap will also work
s: Vec<(i32, String)>,
```
* `map_as_tuple_list` can be replaced with `#[serde_as(as = "Vec<(_, _)>")]`.
* `display_fromstr` can be replaced with `#[serde_as(as = "DisplayFromStr")]`.
* `bytes_or_string` can be replaced with `#[serde_as(as = "BytesOrString")]`.
* `default_on_error` can be replaced with `#[serde_as(as = "DefaultOnError")]`.
* `default_on_null` can be replaced with `#[serde_as(as = "DefaultOnNull")]`.
* `string_empty_as_none` can be replaced with `#[serde_as(as = "NoneAsEmptyString")]`.
* `StringWithSeparator` can now only be used in `serde_as`.
The definition of the `Separator` trait and its implementations have been moved to the `formats` module.
* `json::nested` can be replaced with `#[serde_as(as = "json::JsonString")]`.
* Remove previously deprecated modules.
* `sets_first_value_wins`
* `btreemap_as_tuple_list` and `hashmap_as_tuple_list` can be replaced with `#[serde_as(as = "Vec<(_, _)>")]`.
## [1.14.0] - 2022-05-29
### Added
@ -96,7 +443,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* Account for generics when deriving implementations with `SerializeDisplay` and `DeserializeFromStr` #413
* Provide better error messages when parsing types fails #423
## [1.12.0] - 2022-02-07
### Added

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

@ -10,10 +10,10 @@
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.53"
edition = "2021"
rust-version = "1.60"
name = "serde_with"
version = "1.14.0"
version = "3.0.0"
authors = [
"Jonas Bushart",
"Marcin Kaźmierczak",
@ -34,10 +34,12 @@ keywords = [
"serialization",
"deserialization",
]
categories = ["encoding"]
categories = [
"encoding",
"no-std",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/jonasbb/serde_with"
resolver = "2"
[package.metadata.docs.rs]
all-features = true
@ -47,6 +49,29 @@ rustdoc-args = [
"--generate-link-to-definition",
]
[package.metadata.release]
tag = true
tag-message = "{{crate_name}} v{{version}}"
tag-name = "v{{version}}"
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
replace = """
[Unreleased]
## [{{version}}] - {{date}}"""
search = '\[Unreleased\]'
[[package.metadata.release.pre-release-replacements]]
file = "src/lib.rs"
replace = "https://docs.rs/serde_with/{{version}}/"
search = 'https://docs\.rs/serde_with/[\d.]+/'
[[package.metadata.release.pre-release-replacements]]
file = "README.md"
replace = "https://docs.rs/serde_with/{{version}}/"
search = 'https://docs\.rs/serde_with/[\d.]+/'
[[test]]
name = "base64"
path = "tests/base64.rs"
@ -56,10 +81,10 @@ required-features = [
]
[[test]]
name = "chrono"
path = "tests/chrono.rs"
name = "chrono_0_4"
path = "tests/chrono_0_4.rs"
required-features = [
"chrono",
"chrono_0_4",
"macros",
]
@ -72,10 +97,10 @@ required-features = [
]
[[test]]
name = "indexmap"
path = "tests/indexmap.rs"
name = "indexmap_1"
path = "tests/indexmap_1.rs"
required-features = [
"indexmap",
"indexmap_1",
"macros",
]
@ -105,18 +130,24 @@ name = "derives"
path = "tests/derives/lib.rs"
required-features = ["macros"]
[dependencies.base64_crate]
version = "0.13.0"
optional = true
package = "base64"
[[test]]
name = "with_prefix"
path = "tests/with_prefix.rs"
required-features = ["macros"]
[dependencies.chrono_crate]
version = "0.4.1"
features = [
"clock",
"serde",
"std",
]
[[test]]
name = "rust"
path = "tests/rust.rs"
required-features = ["alloc"]
[dependencies.base64]
version = "0.21.0"
optional = true
default-features = false
[dependencies.chrono_0_4]
version = "0.4.20"
features = ["serde"]
optional = true
default-features = false
package = "chrono"
@ -126,35 +157,39 @@ version = "0.3.3"
optional = true
[dependencies.hex]
version = "0.4.2"
version = "0.4.3"
optional = true
default-features = false
[dependencies.indexmap_crate]
[dependencies.indexmap_1]
version = "1.8"
features = ["serde-1"]
optional = true
default-features = false
package = "indexmap"
[dependencies.serde]
version = "1.0.122"
version = "1.0.157"
features = ["derive"]
default-features = false
[dependencies.serde_json]
version = "1.0.1"
version = "1.0.45"
optional = true
default-features = false
[dependencies.serde_with_macros]
version = "1.5.2"
version = "=3.0.0"
optional = true
[dependencies.time_0_3]
version = "~0.3"
features = ["serde-well-known"]
version = "~0.3.11"
optional = true
default-features = false
package = "time"
[dev-dependencies.expect-test]
version = "1.0.0"
version = "1.3.0"
[dev-dependencies.fnv]
version = "1.0.6"
@ -169,7 +204,7 @@ version = "0.3.16"
version = "1.0.0"
[dev-dependencies.regex]
version = "1.3.9"
version = "1.8.1"
features = ["std"]
default-features = false
@ -177,13 +212,13 @@ default-features = false
version = "1.1.0"
[dev-dependencies.ron]
version = "0.7"
version = "0.8"
[dev-dependencies.rustversion]
version = "1.0.0"
[dev-dependencies.serde-xml-rs]
version = "0.5.0"
version = "0.6.0"
[dev-dependencies.serde_json]
version = "1.0.25"
@ -193,22 +228,59 @@ features = ["preserve_order"]
version = "1.0.124"
[dev-dependencies.serde_yaml]
version = "0.8.21"
version = "0.9.2"
[dev-dependencies.version-sync]
version = "0.9.1"
[features]
base64 = ["base64_crate"]
chrono = ["chrono_crate"]
default = ["macros"]
guide = [
"doc-comment",
alloc = [
"serde/alloc",
"base64?/alloc",
"chrono_0_4?/alloc",
"hex?/alloc",
"serde_json?/alloc",
"time_0_3?/alloc",
]
base64 = [
"dep:base64",
"alloc",
]
chrono = ["chrono_0_4"]
chrono_0_4 = ["dep:chrono_0_4"]
default = [
"std",
"macros",
]
indexmap = ["indexmap_crate"]
json = ["serde_json"]
macros = ["serde_with_macros"]
guide = [
"dep:doc-comment",
"macros",
"std",
]
hex = [
"dep:hex",
"alloc",
]
indexmap = ["indexmap_1"]
indexmap_1 = [
"dep:indexmap_1",
"alloc",
]
json = [
"dep:serde_json",
"alloc",
]
macros = ["dep:serde_with_macros"]
std = [
"alloc",
"serde/std",
"chrono_0_4?/clock",
"chrono_0_4?/std",
"indexmap_1?/std",
"time_0_3?/serde-well-known",
"time_0_3?/std",
]
time_0_3 = ["dep:time_0_3"]
[badges.maintenance]
status = "actively-developed"

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

@ -4,7 +4,7 @@
[![Build Status](https://github.com/jonasbb/serde_with/workflows/Rust%20CI/badge.svg)](https://github.com/jonasbb/serde_with)
[![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4322/badge)](https://bestpractices.coreinfrastructure.org/projects/4322)
[![Binder](https://img.shields.io/badge/Try%20on%20-binder-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gist/jonasbb/18b9aece4c17f617b1c2b3946d29eeb0/HEAD?filepath=serde-with-demo.ipynb)
[![Rustexplorer](https://img.shields.io/badge/Try%20on-rustexplorer-lightgrey?logo=rust&logoColor=orange)](https://www.rustexplorer.com/b/py7ida)
---
@ -12,14 +12,14 @@ This crate provides custom de/serialization helpers to use in combination with [
Some common use cases are:
* De/Serializing a type using the `Display` and `FromStr` traits, e.g., for `u8`, `url::Url`, or `mime::Mime`.
Check [`DisplayFromStr`][] or [`serde_with::rust::display_fromstr`][display_fromstr] for details.
Check [`DisplayFromStr`] for details.
* Support for arrays larger than 32 elements or using const generics.
With `serde_as` large arrays are supported, even if they are nested in other types.
`[bool; 64]`, `Option<[u8; M]>`, and `Box<[[u8; 64]; N]>` are all supported, as [this examples shows](#large-and-const-generic-arrays).
* Skip serializing all empty `Option` types with [`#[skip_serializing_none]`][skip_serializing_none].
* Apply a prefix to each field name of a struct, without changing the de/serialize implementations of the struct using [`with_prefix!`][].
* Deserialize a comma separated list like `#hash,#tags,#are,#great` into a `Vec<String>`.
Check the documentation for [`serde_with::rust::StringWithSeparator::<CommaSeparator>`][StringWithSeparator].
Check the documentation for [`serde_with::StringWithSeparator::<CommaSeparator, T>`][StringWithSeparator].
### Getting Help
@ -30,12 +30,9 @@ For bugs, please open a [new issue](https://github.com/jonasbb/serde_with/issues
## Use `serde_with` in your Project
Add this to your `Cargo.toml`:
```toml
[dependencies.serde_with]
version = "1.14.0"
features = [ "..." ]
```bash
# Add the current version to your Cargo.toml
cargo add serde_with
```
The crate contains different features for integration with other common crates.
@ -44,10 +41,16 @@ Check the [feature flags][] section for information about all available features
## Examples
Annotate your struct or enum to enable the custom de/serializer.
The `#[serde_as]` attribute must be place *before* the `#[derive]`.
The `#[serde_as]` attribute must be placed *before* the `#[derive]`.
The `as` is analogous to the `with` attribute of serde.
You mirror the type structure of the field you want to de/serialize.
You can specify converters for the inner types of a field, e.g., `Vec<DisplayFromStr>`.
The default de/serialization behavior can be restored by using `_` as a placeholder, e.g., `BTreeMap<_, DisplayFromStr>`.
### `DisplayFromStr`
[![Rustexplorer](https://img.shields.io/badge/Try%20on-rustexplorer-lightgrey?logo=rust&logoColor=orange)](https://www.rustexplorer.com/b/py7ida)
```rust
#[serde_as]
#[derive(Deserialize, Serialize)]
@ -67,8 +70,11 @@ Foo {bar: 12}
### Large and const-generic arrays
serde does not support arrays with more than 32 elements or using const-generics.
The `serde_as` attribute allows to circumvent this restriction, even for nested types and nested arrays.
The `serde_as` attribute allows circumventing this restriction, even for nested types and nested arrays.
On top of it, `[u8; N]` (aka, bytes) can use the specialized `"Bytes"` for efficiency much like the `serde_bytes` crate.
[![Rustexplorer](https://img.shields.io/badge/Try%20on-rustexplorer-lightgrey?logo=rust&logoColor=orange)](https://www.rustexplorer.com/b/um0xyi)
```rust
#[serde_as]
#[derive(Deserialize, Serialize)]
@ -81,13 +87,17 @@ struct Arrays<const N: usize, const M: usize> {
#[serde_as(as = "Option<[_; M]>")]
optional: Option<[u8; M]>,
#[serde_as(as = "Bytes")]
bytes: [u8; M],
}
// This allows us to serialize a struct like this
let arrays: Arrays<100, 128> = Arrays {
constgeneric: [true; 100],
nested: Box::new([[111; 64]; 100]),
optional: Some([222; 128])
optional: Some([222; 128]),
bytes: [0x42; 128],
};
assert!(serde_json::to_string(&arrays).is_ok());
```
@ -96,8 +106,9 @@ assert!(serde_json::to_string(&arrays).is_ok());
This situation often occurs with JSON, but other formats also support optional fields.
If many fields are optional, putting the annotations on the structs can become tedious.
The `#[skip_serializing_none]` attribute must be place *before* the `#[derive]`.
The `#[skip_serializing_none]` attribute must be placed *before* the `#[derive]`.
[![Rustexplorer](https://img.shields.io/badge/Try%20on-rustexplorer-lightgrey?logo=rust&logoColor=orange)](https://www.rustexplorer.com/b/xr1tm0)
```rust
#[skip_serializing_none]
#[derive(Deserialize, Serialize)]
@ -121,52 +132,65 @@ Foo {a: None, b: None, c: None, d: Some(4), e: None, f: None, g: Some(7)}
### Advanced `serde_as` usage
This example is mainly supposed to highlight the flexibility of the `serde_as`-annotation compared to [serde's with-annotation][with-annotation].
More details about `serde_as` can be found in the [user guide][].
More details about `serde_as` can be found in the [user guide].
```rust
use std::time::Duration;
#[serde_as]
#[derive(Deserialize, Serialize)]
struct Foo {
// Serialize them into a list of number as seconds
#[serde_as(as = "Vec<DurationSeconds>")]
durations: Vec<Duration>,
// We can treat a Vec like a map with duplicates.
// JSON only allows string keys, so convert i32 to strings
// The bytes will be hex encoded
#[serde_as(as = "BTreeMap<DisplayFromStr, Hex>")]
bytes: Vec<(i32, Vec<u8>)>,
enum Foo {
Durations(
// Serialize them into a list of number as seconds
#[serde_as(as = "Vec<DurationSeconds>")]
Vec<Duration>,
),
Bytes {
// We can treat a Vec like a map with duplicates.
// JSON only allows string keys, so convert i32 to strings
// The bytes will be hex encoded
#[serde_as(as = "Map<DisplayFromStr, Hex>")]
bytes: Vec<(i32, Vec<u8>)>,
}
}
// This will serialize
Foo {
durations: vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)],
Foo::Durations(
vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)]
)
// into this JSON
{
"Durations": [5, 3600, 0]
}
// and serializes
Foo::Bytes {
bytes: vec![
(1, vec![0, 1, 2]),
(-100, vec![100, 200, 255]),
(1, vec![0, 111, 222]),
],
}
// into this JSON
{
"durations": [5, 3600, 0],
"bytes": {
"1": "000102",
"-100": "64c8ff",
"1": "006fde"
"Bytes": {
"bytes": {
"1": "000102",
"-100": "64c8ff",
"1": "006fde"
}
}
}
```
[`DisplayFromStr`]: https://docs.rs/serde_with/1.14.0/serde_with/struct.DisplayFromStr.html
[`with_prefix!`]: https://docs.rs/serde_with/1.14.0/serde_with/macro.with_prefix.html
[display_fromstr]: https://docs.rs/serde_with/1.14.0/serde_with/rust/display_fromstr/index.html
[feature flags]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
[skip_serializing_none]: https://docs.rs/serde_with/1.14.0/serde_with/attr.skip_serializing_none.html
[StringWithSeparator]: https://docs.rs/serde_with/1.14.0/serde_with/rust/struct.StringWithSeparator.html
[user guide]: https://docs.rs/serde_with/1.14.0/serde_with/guide/index.html
[`DisplayFromStr`]: https://docs.rs/serde_with/3.0.0/serde_with/struct.DisplayFromStr.html
[`with_prefix!`]: https://docs.rs/serde_with/3.0.0/serde_with/macro.with_prefix.html
[feature flags]: https://docs.rs/serde_with/3.0.0/serde_with/guide/feature_flags/index.html
[skip_serializing_none]: https://docs.rs/serde_with/3.0.0/serde_with/attr.skip_serializing_none.html
[StringWithSeparator]: https://docs.rs/serde_with/3.0.0/serde_with/struct.StringWithSeparator.html
[user guide]: https://docs.rs/serde_with/3.0.0/serde_with/guide/index.html
[with-annotation]: https://serde.rs/field-attrs.html#with
[as-annotation]: https://docs.rs/serde_with/1.14.0/serde_with/guide/serde_as/index.html
[as-annotation]: https://docs.rs/serde_with/3.0.0/serde_with/guide/serde_as/index.html
## License

161
third_party/rust/serde_with/src/base64.rs поставляемый
Просмотреть файл

@ -4,14 +4,7 @@
//!
//! Please check the documentation on the [`Base64`] type for details.
use crate::{formats, DeserializeAs, SerializeAs};
use alloc::{format, string::String, vec::Vec};
use core::{
convert::{TryFrom, TryInto},
default::Default,
marker::PhantomData,
};
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use crate::prelude::*;
/// Serialize bytes with base64
///
@ -19,7 +12,7 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
/// It works on any type implementing `AsRef<[u8]>` for serialization and `TryFrom<Vec<u8>>` for deserialization.
///
/// The type allows customizing the character set and the padding behavior.
/// The `CHARSET` is a type implementing [`CharacterSet`].
/// The `ALPHABET` is a type implementing [`Alphabet`].
/// `PADDING` specifies if serializing should emit padding.
/// Deserialization always supports padded and unpadded formats.
/// [`formats::Padded`] emits padding and [`formats::Unpadded`] leaves it off.
@ -69,137 +62,171 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
// The padding might be better as `const PADDING: bool = true`
// https://blog.rust-lang.org/inside-rust/2021/09/06/Splitting-const-generics.html#featureconst_generics_default/
#[derive(Copy, Clone, Debug, Default)]
pub struct Base64<CHARSET: CharacterSet = Standard, PADDING: formats::Format = formats::Padded>(
PhantomData<(CHARSET, PADDING)>,
pub struct Base64<ALPHABET: Alphabet = Standard, PADDING: formats::Format = formats::Padded>(
PhantomData<(ALPHABET, PADDING)>,
);
impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Padded>
impl<T, ALPHABET> SerializeAs<T> for Base64<ALPHABET, formats::Padded>
where
T: AsRef<[u8]>,
CHARSET: CharacterSet,
ALPHABET: Alphabet,
{
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), true))
.serialize(serializer)
use ::base64::Engine as _;
::base64::engine::GeneralPurpose::new(
&ALPHABET::charset(),
::base64::engine::general_purpose::PAD,
)
.encode(source)
.serialize(serializer)
}
}
impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Unpadded>
impl<T, ALPHABET> SerializeAs<T> for Base64<ALPHABET, formats::Unpadded>
where
T: AsRef<[u8]>,
CHARSET: CharacterSet,
ALPHABET: Alphabet,
{
fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), false))
.serialize(serializer)
use ::base64::Engine as _;
::base64::engine::GeneralPurpose::new(
&ALPHABET::charset(),
::base64::engine::general_purpose::NO_PAD,
)
.encode(source)
.serialize(serializer)
}
}
impl<'de, T, CHARSET, FORMAT> DeserializeAs<'de, T> for Base64<CHARSET, FORMAT>
// Our decoders uniformly do not care about padding.
const PAD_INDIFFERENT: ::base64::engine::GeneralPurposeConfig =
::base64::engine::GeneralPurposeConfig::new()
.with_decode_padding_mode(::base64::engine::DecodePaddingMode::Indifferent);
impl<'de, T, ALPHABET, FORMAT> DeserializeAs<'de, T> for Base64<ALPHABET, FORMAT>
where
T: TryFrom<Vec<u8>>,
CHARSET: CharacterSet,
ALPHABET: Alphabet,
FORMAT: formats::Format,
{
fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
{
String::deserialize(deserializer)
.and_then(|s| {
base64_crate::decode_config(
&*s,
base64_crate::Config::new(CHARSET::charset(), false),
)
.map_err(Error::custom)
})
.and_then(|vec: Vec<u8>| {
let length = vec.len();
vec.try_into().map_err(|_e: T::Error| {
Error::custom(format!(
"Can't convert a Byte Vector of length {} to the output type.",
length
struct Helper<T, ALPHABET>(PhantomData<(T, ALPHABET)>);
impl<'de, T, ALPHABET> Visitor<'de> for Helper<T, ALPHABET>
where
T: TryFrom<Vec<u8>>,
ALPHABET: Alphabet,
{
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a base64 encoded string")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: DeError,
{
use ::base64::Engine as _;
let bytes =
::base64::engine::GeneralPurpose::new(&ALPHABET::charset(), PAD_INDIFFERENT)
.decode(value)
.map_err(DeError::custom)?;
let length = bytes.len();
bytes.try_into().map_err(|_e: T::Error| {
DeError::custom(format_args!(
"Can't convert a Byte Vector of length {length} to the output type."
))
})
})
}
}
deserializer.deserialize_str(Helper::<T, ALPHABET>(PhantomData))
}
}
/// A base64 character set from [this list](base64_crate::CharacterSet).
pub trait CharacterSet {
/// Return a specific character set.
///
/// Return one enum variant of the [`base64::CharacterSet`](base64_crate::CharacterSet) enum.
fn charset() -> base64_crate::CharacterSet;
mod sealed {
pub trait Sealed {}
impl Sealed for super::Standard {}
impl Sealed for super::UrlSafe {}
impl Sealed for super::Crypt {}
impl Sealed for super::Bcrypt {}
impl Sealed for super::ImapMutf7 {}
impl Sealed for super::BinHex {}
}
/// A base64 alphabet
pub trait Alphabet: sealed::Sealed {
/// Return a specific alphabet.
fn charset() -> ::base64::alphabet::Alphabet;
}
/// The standard character set (uses `+` and `/`).
///
/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
#[derive(Copy, Clone, Debug, Default)]
pub struct Standard;
impl CharacterSet for Standard {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Standard
impl Alphabet for Standard {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::STANDARD
}
}
/// The URL safe character set (uses `-` and `_`).
///
/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
#[derive(Copy, Clone, Debug, Default)]
pub struct UrlSafe;
impl CharacterSet for UrlSafe {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::UrlSafe
impl Alphabet for UrlSafe {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::URL_SAFE
}
}
/// The `crypt(3)` character set (uses `./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`).
///
/// Not standardized, but folk wisdom on the net asserts that this alphabet is what crypt uses.
#[derive(Copy, Clone, Debug, Default)]
pub struct Crypt;
impl CharacterSet for Crypt {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Crypt
impl Alphabet for Crypt {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::CRYPT
}
}
/// The bcrypt character set (uses `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`).
#[derive(Copy, Clone, Debug, Default)]
pub struct Bcrypt;
impl CharacterSet for Bcrypt {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::Bcrypt
impl Alphabet for Bcrypt {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::BCRYPT
}
}
/// The character set used in IMAP-modified UTF-7 (uses `+` and `,`).
///
/// See [RFC 3501](https://tools.ietf.org/html/rfc3501#section-5.1.3).
#[derive(Copy, Clone, Debug, Default)]
pub struct ImapMutf7;
impl CharacterSet for ImapMutf7 {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::ImapMutf7
impl Alphabet for ImapMutf7 {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::IMAP_MUTF7
}
}
/// The character set used in BinHex 4.0 files.
///
/// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt).
#[derive(Copy, Clone, Debug, Default)]
pub struct BinHex;
impl CharacterSet for BinHex {
fn charset() -> base64_crate::CharacterSet {
base64_crate::CharacterSet::BinHex
impl Alphabet for BinHex {
fn charset() -> ::base64::alphabet::Alphabet {
::base64::alphabet::BIN_HEX
}
}

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

@ -1,38 +1,31 @@
//! De/Serialization of [chrono][] types
//! De/Serialization of [chrono] types
//!
//! This modules is only available if using the `chrono` feature of the crate.
//! This modules is only available if using the `chrono_0_4` feature of the crate.
//!
//! [chrono]: https://docs.rs/chrono/
use crate::{
de::DeserializeAs,
formats::{Flexible, Format, Strict, Strictness},
ser::SerializeAs,
utils::duration::{DurationSigned, Sign},
DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
prelude::*,
};
use alloc::{format, string::String, vec::Vec};
use chrono_crate::{DateTime, Duration, Local, NaiveDateTime, TimeZone, Utc};
use core::fmt;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "std")]
use ::chrono_0_4::Local;
use ::chrono_0_4::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};
/// Create a [`DateTime`] for the Unix Epoch using the [`Utc`] timezone
fn unix_epoch_utc() -> DateTime<Utc> {
DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc)
DateTime::<Utc>::from_utc(unix_epoch_naive(), Utc)
}
/// Create a [`DateTime`] for the Unix Epoch using the [`Local`] timezone
#[cfg(feature = "std")]
fn unix_epoch_local() -> DateTime<Local> {
DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc).with_timezone(&Local)
unix_epoch_utc().with_timezone(&Local)
}
/// Create a [`NaiveDateTime`] for the Unix Epoch
fn unix_epoch_naive() -> NaiveDateTime {
NaiveDateTime::from_timestamp(0, 0)
NaiveDateTime::from_timestamp_opt(0, 0).unwrap()
}
/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
@ -42,12 +35,12 @@ fn unix_epoch_naive() -> NaiveDateTime {
/// # Examples
///
/// ```
/// # use chrono_crate::{DateTime, Utc};
/// # use chrono_0_4::{DateTime, Utc};
/// # use serde::Deserialize;
/// #
/// #[derive(Debug, Deserialize)]
/// struct S {
/// #[serde(with = "serde_with::chrono::datetime_utc_ts_seconds_from_any")]
/// #[serde(with = "serde_with::chrono_0_4::datetime_utc_ts_seconds_from_any")]
/// date: DateTime<Utc>,
/// }
///
@ -58,10 +51,10 @@ fn unix_epoch_naive() -> NaiveDateTime {
/// // and strings with numbers, for high-precision values
/// assert!(serde_json::from_str::<S>(r#"{ "date": "1478563200.123" }"#).is_ok());
/// ```
// Requires float operations from std
#[cfg(feature = "std")]
pub mod datetime_utc_ts_seconds_from_any {
use super::*;
use chrono_crate::{DateTime, NaiveDateTime, Utc};
use serde::de::{Deserializer, Error, Unexpected, Visitor};
/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
@ -79,37 +72,35 @@ pub mod datetime_utc_ts_seconds_from_any {
fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let ndt = NaiveDateTime::from_timestamp_opt(value, 0);
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
)))
}
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let ndt = NaiveDateTime::from_timestamp_opt(value as i64, 0);
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
)))
}
}
fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let seconds = value.trunc() as i64;
let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32;
@ -117,16 +108,15 @@ pub mod datetime_utc_ts_seconds_from_any {
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
)))
}
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let parts: Vec<_> = value.split('.').collect();
@ -137,22 +127,20 @@ pub mod datetime_utc_ts_seconds_from_any {
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
)))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
}
[seconds, subseconds] => {
if let Ok(seconds) = seconds.parse() {
let subseclen = subseconds.chars().count() as u32;
if subseclen > 9 {
return Err(Error::custom(format!(
"DateTimes only support nanosecond precision but '{}' has more than 9 digits.",
value
return Err(DeError::custom(format_args!(
"DateTimes only support nanosecond precision but '{value}' has more than 9 digits."
)));
}
@ -163,20 +151,19 @@ pub mod datetime_utc_ts_seconds_from_any {
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{value}'"
)))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
}
_ => Err(Error::invalid_value(Unexpected::Str(value), &self)),
_ => Err(DeError::invalid_value(Unexpected::Str(value), &self)),
}
}
}
@ -204,7 +191,7 @@ impl<'de> DeserializeAs<'de, NaiveDateTime> for DateTime<Utc> {
}
}
/// Convert a [`chrono::Duration`] into a [`DurationSigned`]
/// Convert a [`chrono_0_4::Duration`] into a [`DurationSigned`]
fn duration_into_duration_signed(dur: &Duration) -> DurationSigned {
match dur.to_std() {
Ok(dur) => DurationSigned::with_duration(Sign::Positive, dur),
@ -218,7 +205,7 @@ fn duration_into_duration_signed(dur: &Duration) -> DurationSigned {
}
}
/// Convert a [`DurationSigned`] into a [`chrono::Duration`]
/// Convert a [`DurationSigned`] into a [`chrono_0_4::Duration`]
fn duration_from_duration_signed<'de, D>(dur: DurationSigned) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
@ -226,9 +213,8 @@ where
let mut chrono_dur = match Duration::from_std(dur.duration) {
Ok(dur) => dur,
Err(msg) => {
return Err(de::Error::custom(format!(
"Duration is outside of the representable range: {}",
msg
return Err(DeError::custom(format_args!(
"Duration is outside of the representable range: {msg}"
)))
}
};
@ -294,6 +280,16 @@ use_duration_signed_ser!(
Duration; duration_into_duration_signed =>
{i64, STRICTNESS => STRICTNESS: Strictness}
{f64, STRICTNESS => STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
DurationSeconds DurationSeconds,
DurationMilliSeconds DurationMilliSeconds,
DurationMicroSeconds DurationMicroSeconds,
DurationNanoSeconds DurationNanoSeconds,
=> {
Duration; duration_into_duration_signed =>
{String, STRICTNESS => STRICTNESS: Strictness}
}
);
@ -306,6 +302,16 @@ use_duration_signed_ser!(
DateTime<TZ>; datetime_to_duration =>
{i64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
{f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
DateTime<TZ>; datetime_to_duration =>
{String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
}
);
@ -318,6 +324,16 @@ use_duration_signed_ser!(
NaiveDateTime; naive_datetime_to_duration =>
{i64, STRICTNESS => STRICTNESS: Strictness}
{f64, STRICTNESS => STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
NaiveDateTime; naive_datetime_to_duration =>
{String, STRICTNESS => STRICTNESS: Strictness}
}
);
@ -331,6 +347,16 @@ use_duration_signed_ser!(
=> {
Duration; duration_into_duration_signed =>
{f64, STRICTNESS => STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
DurationSecondsWithFrac DurationSecondsWithFrac,
DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
Duration; duration_into_duration_signed =>
{String, STRICTNESS => STRICTNESS: Strictness}
}
);
@ -342,6 +368,16 @@ use_duration_signed_ser!(
=> {
DateTime<TZ>; datetime_to_duration =>
{f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
DateTime<TZ>; datetime_to_duration =>
{String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
}
);
@ -353,6 +389,16 @@ use_duration_signed_ser!(
=> {
NaiveDateTime; naive_datetime_to_duration =>
{f64, STRICTNESS => STRICTNESS: Strictness}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_ser!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
NaiveDateTime; naive_datetime_to_duration =>
{String, STRICTNESS => STRICTNESS: Strictness}
}
);
@ -397,6 +443,7 @@ where
Ok(unix_epoch_utc() + duration_from_duration_signed::<D>(dur)?)
}
#[cfg(feature = "std")]
fn duration_to_datetime_local<'de, D>(dur: DurationSigned) -> Result<DateTime<Local>, D::Error>
where
D: Deserializer<'de>,
@ -420,11 +467,31 @@ use_duration_signed_de!(
=> {
Duration; duration_from_duration_signed =>
{i64, Strict =>}
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
DurationSeconds DurationSeconds,
DurationMilliSeconds DurationMilliSeconds,
DurationMicroSeconds DurationMicroSeconds,
DurationNanoSeconds DurationNanoSeconds,
=> {
Duration; duration_from_duration_signed =>
{String, Strict =>}
}
);
#[cfg(feature = "std")]
use_duration_signed_de!(
DurationSeconds DurationSeconds,
DurationMilliSeconds DurationMilliSeconds,
DurationMicroSeconds DurationMicroSeconds,
DurationNanoSeconds DurationNanoSeconds,
=> {
Duration; duration_from_duration_signed =>
{f64, Strict =>}
}
);
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
@ -433,11 +500,32 @@ use_duration_signed_de!(
=> {
DateTime<Utc>; duration_to_datetime_utc =>
{i64, Strict =>}
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
DateTime<Utc>; duration_to_datetime_utc =>
{String, Strict =>}
}
);
#[cfg(feature = "std")]
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
DateTime<Utc>; duration_to_datetime_utc =>
{f64, Strict =>}
}
);
#[cfg(feature = "std")]
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
@ -459,11 +547,31 @@ use_duration_signed_de!(
=> {
NaiveDateTime; duration_to_naive_datetime =>
{i64, Strict =>}
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
NaiveDateTime; duration_to_naive_datetime =>
{String, Strict =>}
}
);
#[cfg(feature = "std")]
use_duration_signed_de!(
TimestampSeconds DurationSeconds,
TimestampMilliSeconds DurationMilliSeconds,
TimestampMicroSeconds DurationMicroSeconds,
TimestampNanoSeconds DurationNanoSeconds,
=> {
NaiveDateTime; duration_to_naive_datetime =>
{f64, Strict =>}
}
);
// Duration/Timestamp WITH FRACTIONS
use_duration_signed_de!(
@ -474,10 +582,20 @@ use_duration_signed_de!(
=> {
Duration; duration_from_duration_signed =>
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
DurationSecondsWithFrac DurationSecondsWithFrac,
DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
Duration; duration_from_duration_signed =>
{String, Strict =>}
}
);
use_duration_signed_de!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
@ -486,10 +604,21 @@ use_duration_signed_de!(
=> {
DateTime<Utc>; duration_to_datetime_utc =>
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
DateTime<Utc>; duration_to_datetime_utc =>
{String, Strict =>}
}
);
#[cfg(feature = "std")]
use_duration_signed_de!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
@ -510,7 +639,17 @@ use_duration_signed_de!(
=> {
NaiveDateTime; duration_to_naive_datetime =>
{f64, Strict =>}
{String, Strict =>}
{FORMAT, Flexible => FORMAT: Format}
}
);
#[cfg(feature = "alloc")]
use_duration_signed_de!(
TimestampSecondsWithFrac DurationSecondsWithFrac,
TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
=> {
NaiveDateTime; duration_to_naive_datetime =>
{String, Strict =>}
}
);

1894
third_party/rust/serde_with/src/content/de.rs поставляемый Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -2,4 +2,7 @@
//!
//! <https://github.com/serde-rs/serde/blob/55a7cedd737278a9d75a2efd038c6f38b8c38bd6/serde/src/private/ser.rs#L338-L997>
#![cfg(not(tarpaulin_include))]
pub(crate) mod de;
pub(crate) mod ser;

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

@ -11,11 +11,8 @@
//! The types support 128-bit integers, which is supported for all targets in Rust 1.40+.
//! The [`ContentSerializer`] can also be configured to human readable or compact representation.
use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
use core::marker::PhantomData;
use serde::ser::{self, Serialize, Serializer};
use crate::prelude::*;
#[derive(Debug)]
pub(crate) enum Content {
Bool(bool),
@ -61,6 +58,16 @@ pub(crate) enum Content {
),
}
impl Content {
pub(crate) fn as_str(&self) -> Option<&str> {
match self {
Self::String(ref x) => Some(x),
Self::Bytes(x) => core::str::from_utf8(x).ok(),
_ => None,
}
}
}
impl Serialize for Content {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -94,7 +101,6 @@ impl Serialize for Content {
}
Content::Seq(ref elements) => elements.serialize(serializer),
Content::Tuple(ref elements) => {
use serde::ser::SerializeTuple;
let mut tuple = serializer.serialize_tuple(elements.len())?;
for e in elements {
tuple.serialize_element(e)?;
@ -102,7 +108,6 @@ impl Serialize for Content {
tuple.end()
}
Content::TupleStruct(n, ref fields) => {
use serde::ser::SerializeTupleStruct;
let mut ts = serializer.serialize_tuple_struct(n, fields.len())?;
for f in fields {
ts.serialize_field(f)?;
@ -110,7 +115,6 @@ impl Serialize for Content {
ts.end()
}
Content::TupleVariant(n, i, v, ref fields) => {
use serde::ser::SerializeTupleVariant;
let mut tv = serializer.serialize_tuple_variant(n, i, v, fields.len())?;
for f in fields {
tv.serialize_field(f)?;
@ -118,25 +122,22 @@ impl Serialize for Content {
tv.end()
}
Content::Map(ref entries) => {
use serde::ser::SerializeMap;
let mut map = serializer.serialize_map(Some(entries.len()))?;
for &(ref k, ref v) in entries {
for (k, v) in entries {
map.serialize_entry(k, v)?;
}
map.end()
}
Content::Struct(n, ref fields) => {
use serde::ser::SerializeStruct;
let mut s = serializer.serialize_struct(n, fields.len())?;
for &(k, ref v) in fields {
for (k, v) in fields {
s.serialize_field(k, v)?;
}
s.end()
}
Content::StructVariant(n, i, v, ref fields) => {
use serde::ser::SerializeStructVariant;
let mut sv = serializer.serialize_struct_variant(n, i, v, fields.len())?;
for &(k, ref v) in fields {
for (k, v) in fields {
sv.serialize_field(k, v)?;
}
sv.end()
@ -167,18 +168,18 @@ impl<E> Default for ContentSerializer<E> {
impl<E> Serializer for ContentSerializer<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
type SerializeSeq = SerializeSeq<E>;
type SerializeTuple = SerializeTuple<E>;
type SerializeTupleStruct = SerializeTupleStruct<E>;
type SerializeTupleVariant = SerializeTupleVariant<E>;
type SerializeMap = SerializeMap<E>;
type SerializeStruct = SerializeStruct<E>;
type SerializeStructVariant = SerializeStructVariant<E>;
type SerializeSeq = SeqSerialize<E>;
type SerializeTuple = TupleSerialize<E>;
type SerializeTupleStruct = TupleStructSerialize<E>;
type SerializeTupleVariant = TupleVariantSerialize<E>;
type SerializeMap = MapSerialize<E>;
type SerializeStruct = StructSerialize<E>;
type SerializeStructVariant = StructVariantSerialize<E>;
fn is_human_readable(&self) -> bool {
self.is_human_readable
@ -309,7 +310,7 @@ where
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
Ok(SerializeSeq {
Ok(SeqSerialize {
is_human_readable: self.is_human_readable,
elements: Vec::with_capacity(len.unwrap_or(0)),
error: PhantomData,
@ -317,7 +318,7 @@ where
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
Ok(SerializeTuple {
Ok(TupleSerialize {
is_human_readable: self.is_human_readable,
elements: Vec::with_capacity(len),
error: PhantomData,
@ -329,7 +330,7 @@ where
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, E> {
Ok(SerializeTupleStruct {
Ok(TupleStructSerialize {
is_human_readable: self.is_human_readable,
name,
fields: Vec::with_capacity(len),
@ -344,7 +345,7 @@ where
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, E> {
Ok(SerializeTupleVariant {
Ok(TupleVariantSerialize {
is_human_readable: self.is_human_readable,
name,
variant_index,
@ -355,7 +356,7 @@ where
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
Ok(SerializeMap {
Ok(MapSerialize {
is_human_readable: self.is_human_readable,
entries: Vec::with_capacity(len.unwrap_or(0)),
key: None,
@ -364,7 +365,7 @@ where
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, E> {
Ok(SerializeStruct {
Ok(StructSerialize {
is_human_readable: self.is_human_readable,
name,
fields: Vec::with_capacity(len),
@ -379,7 +380,7 @@ where
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, E> {
Ok(SerializeStructVariant {
Ok(StructVariantSerialize {
is_human_readable: self.is_human_readable,
name,
variant_index,
@ -390,15 +391,15 @@ where
}
}
pub(crate) struct SerializeSeq<E> {
pub(crate) struct SeqSerialize<E> {
is_human_readable: bool,
elements: Vec<Content>,
error: PhantomData<E>,
}
impl<E> ser::SerializeSeq for SerializeSeq<E>
impl<E> SerializeSeq for SeqSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -417,15 +418,15 @@ where
}
}
pub(crate) struct SerializeTuple<E> {
pub(crate) struct TupleSerialize<E> {
is_human_readable: bool,
elements: Vec<Content>,
error: PhantomData<E>,
}
impl<E> ser::SerializeTuple for SerializeTuple<E>
impl<E> SerializeTuple for TupleSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -444,16 +445,16 @@ where
}
}
pub(crate) struct SerializeTupleStruct<E> {
pub(crate) struct TupleStructSerialize<E> {
is_human_readable: bool,
name: &'static str,
fields: Vec<Content>,
error: PhantomData<E>,
}
impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
impl<E> SerializeTupleStruct for TupleStructSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -472,7 +473,7 @@ where
}
}
pub(crate) struct SerializeTupleVariant<E> {
pub(crate) struct TupleVariantSerialize<E> {
is_human_readable: bool,
name: &'static str,
variant_index: u32,
@ -481,9 +482,9 @@ pub(crate) struct SerializeTupleVariant<E> {
error: PhantomData<E>,
}
impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
impl<E> SerializeTupleVariant for TupleVariantSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -507,16 +508,16 @@ where
}
}
pub(crate) struct SerializeMap<E> {
pub(crate) struct MapSerialize<E> {
is_human_readable: bool,
entries: Vec<(Content, Content)>,
key: Option<Content>,
error: PhantomData<E>,
}
impl<E> ser::SerializeMap for SerializeMap<E>
impl<E> SerializeMap for MapSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -559,16 +560,16 @@ where
}
}
pub(crate) struct SerializeStruct<E> {
pub(crate) struct StructSerialize<E> {
is_human_readable: bool,
name: &'static str,
fields: Vec<(&'static str, Content)>,
error: PhantomData<E>,
}
impl<E> ser::SerializeStruct for SerializeStruct<E>
impl<E> SerializeStruct for StructSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;
@ -587,7 +588,7 @@ where
}
}
pub(crate) struct SerializeStructVariant<E> {
pub(crate) struct StructVariantSerialize<E> {
is_human_readable: bool,
name: &'static str,
variant_index: u32,
@ -596,9 +597,9 @@ pub(crate) struct SerializeStructVariant<E> {
error: PhantomData<E>,
}
impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
impl<E> SerializeStructVariant for StructVariantSerialize<E>
where
E: ser::Error,
E: SerError,
{
type Ok = Content;
type Error = E;

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

@ -1,338 +0,0 @@
use super::*;
use crate::utils::{MapIter, SeqIter};
use alloc::{borrow::Cow, boxed::Box, collections::BTreeMap, string::String, vec::Vec};
use core::{convert::TryInto, fmt, mem::MaybeUninit};
use serde::de::*;
use std::collections::HashMap;
// TODO this should probably be moved into the utils module when const generics are available for MSRV
/// # Safety
/// The code follow exactly the pattern of initializing an array element-by-element from the standard library.
/// <https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element>
fn array_from_iterator<I, T, E, const N: usize>(
mut iter: I,
expected: &dyn Expected,
) -> Result<[T; N], E>
where
I: Iterator<Item = Result<T, E>>,
E: Error,
{
fn drop_array_elems<T, const N: usize>(num: usize, mut arr: [MaybeUninit<T>; N]) {
arr[..num].iter_mut().for_each(|elem| {
// TODO This would be better with assume_init_drop nightly function
// https://github.com/rust-lang/rust/issues/63567
unsafe { core::ptr::drop_in_place(elem.as_mut_ptr()) };
});
}
// Create an uninitialized array of `MaybeUninit`. The `assume_init` is
// safe because the type we are claiming to have initialized here is a
// bunch of `MaybeUninit`s, which do not require initialization.
//
// TODO could be simplified with nightly maybe_uninit_uninit_array feature
// https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.uninit_array
let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
// Dropping a `MaybeUninit` does nothing. Thus using raw pointer
// assignment instead of `ptr::write` does not cause the old
// uninitialized value to be dropped. Also if there is a panic during
// this loop, we have a memory leak, but there is no memory safety
// issue.
for (idx, elem) in arr[..].iter_mut().enumerate() {
*elem = match iter.next() {
Some(Ok(value)) => MaybeUninit::new(value),
Some(Err(err)) => {
drop_array_elems(idx, arr);
return Err(err);
}
None => {
drop_array_elems(idx, arr);
return Err(Error::invalid_length(idx, expected));
}
};
}
// Everything is initialized. Transmute the array to the
// initialized type.
// A normal transmute is not possible because of:
// https://github.com/rust-lang/rust/issues/61956
Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
}
impl<'de, T, As, const N: usize> DeserializeAs<'de, [T; N]> for [As; N]
where
As: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<[T; N], D::Error>
where
D: Deserializer<'de>,
{
struct ArrayVisitor<T, const M: usize>(PhantomData<T>);
impl<'de, T, As, const M: usize> Visitor<'de> for ArrayVisitor<DeserializeAsWrap<T, As>, M>
where
As: DeserializeAs<'de, T>,
{
type Value = [T; M];
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_fmt(format_args!("an array of size {}", M))
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
array_from_iterator(
SeqIter::new(seq).map(|res: Result<DeserializeAsWrap<T, As>, A::Error>| {
res.map(|t| t.into_inner())
}),
&self,
)
}
}
deserializer.deserialize_tuple(N, ArrayVisitor::<DeserializeAsWrap<T, As>, N>(PhantomData))
}
}
macro_rules! tuple_seq_as_map_impl_intern {
($tyorig:ty, $ty:ident <KAs, VAs>) => {
#[allow(clippy::implicit_hasher)]
impl<'de, K, KAs, V, VAs, const N: usize> DeserializeAs<'de, $tyorig> for $ty<KAs, VAs>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
fn deserialize_as<D>(deserializer: D) -> Result<$tyorig, D::Error>
where
D: Deserializer<'de>,
{
struct MapVisitor<K, KAs, V, VAs, const M: usize> {
marker: PhantomData<(K, KAs, V, VAs)>,
}
impl<'de, K, KAs, V, VAs, const M: usize> Visitor<'de> for MapVisitor<K, KAs, V, VAs, M>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
type Value = [(K, V); M];
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_fmt(format_args!("a map of length {}", M))
}
fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
array_from_iterator(MapIter::new(access).map(
|res: Result<(DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>), A::Error>| {
res.map(|(k, v)| (k.into_inner(), v.into_inner()))
}
), &self)
}
}
let visitor = MapVisitor::<K, KAs, V, VAs, N> {
marker: PhantomData,
};
deserializer.deserialize_map(visitor)
}
}
}
}
tuple_seq_as_map_impl_intern!([(K, V); N], BTreeMap<KAs, VAs>);
tuple_seq_as_map_impl_intern!([(K, V); N], HashMap<KAs, VAs>);
impl<'de, const N: usize> DeserializeAs<'de, [u8; N]> for Bytes {
fn deserialize_as<D>(deserializer: D) -> Result<[u8; N], D::Error>
where
D: Deserializer<'de>,
{
struct ArrayVisitor<const M: usize>;
impl<'de, const M: usize> Visitor<'de> for ArrayVisitor<M> {
type Value = [u8; M];
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_fmt(format_args!("an byte array of size {}", M))
}
fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
array_from_iterator(SeqIter::new(seq), &self)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
v.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
v.as_bytes()
.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))
}
}
deserializer.deserialize_bytes(ArrayVisitor::<N>)
}
}
impl<'de, const N: usize> DeserializeAs<'de, &'de [u8; N]> for Bytes {
fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8; N], D::Error>
where
D: Deserializer<'de>,
{
struct ArrayVisitor<const M: usize>;
impl<'de, const M: usize> Visitor<'de> for ArrayVisitor<M> {
type Value = &'de [u8; M];
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_fmt(format_args!("a borrowed byte array of size {}", M))
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: Error,
{
v.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: Error,
{
v.as_bytes()
.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))
}
}
deserializer.deserialize_bytes(ArrayVisitor::<N>)
}
}
impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for Bytes {
fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>
where
D: Deserializer<'de>,
{
struct CowVisitor<const M: usize>;
impl<'de, const M: usize> Visitor<'de> for CowVisitor<M> {
type Value = Cow<'de, [u8; M]>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a byte array")
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Borrowed(
v.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))?,
))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Borrowed(
v.as_bytes()
.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))?,
))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(
v.to_vec()
.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))?,
))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(
v.as_bytes()
.to_vec()
.try_into()
.map_err(|_| Error::invalid_length(v.len(), &self))?,
))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
let len = v.len();
Ok(Cow::Owned(
v.try_into()
.map_err(|_| Error::invalid_length(len, &self))?,
))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
let len = v.len();
Ok(Cow::Owned(
v.into_bytes()
.try_into()
.map_err(|_| Error::invalid_length(len, &self))?,
))
}
fn visit_seq<V>(self, seq: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
Ok(Cow::Owned(array_from_iterator(SeqIter::new(seq), &self)?))
}
}
deserializer.deserialize_bytes(CowVisitor)
}
}
impl<'de, const N: usize> DeserializeAs<'de, Box<[u8; N]>> for Bytes {
fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8; N]>, D::Error>
where
D: Deserializer<'de>,
{
Bytes::deserialize_as(deserializer).map(Box::new)
}
}
impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for BorrowCow {
fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>
where
D: Deserializer<'de>,
{
Bytes::deserialize_as(deserializer)
}
}

223
third_party/rust/serde_with/src/de/duplicates.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,223 @@
use super::impls::{foreach_map_create, foreach_set_create};
use crate::{
duplicate_key_impls::{
DuplicateInsertsFirstWinsMap, DuplicateInsertsLastWinsSet, PreventDuplicateInsertsMap,
PreventDuplicateInsertsSet,
},
prelude::*,
MapFirstKeyWins, MapPreventDuplicates, SetLastValueWins, SetPreventDuplicates,
};
#[cfg(feature = "indexmap_1")]
use indexmap_1::{IndexMap, IndexSet};
struct SetPreventDuplicatesVisitor<SET, T, TAs>(PhantomData<(SET, T, TAs)>);
impl<'de, SET, T, TAs> Visitor<'de> for SetPreventDuplicatesVisitor<SET, T, TAs>
where
SET: PreventDuplicateInsertsSet<T>,
TAs: DeserializeAs<'de, T>,
{
type Value = SET;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = Self::Value::new(access.size_hint());
while let Some(value) = access.next_element::<DeserializeAsWrap<T, TAs>>()? {
if !values.insert(value.into_inner()) {
return Err(DeError::custom("invalid entry: found duplicate value"));
};
}
Ok(values)
}
}
struct SetLastValueWinsVisitor<SET, T, TAs>(PhantomData<(SET, T, TAs)>);
impl<'de, SET, T, TAs> Visitor<'de> for SetLastValueWinsVisitor<SET, T, TAs>
where
SET: DuplicateInsertsLastWinsSet<T>,
TAs: DeserializeAs<'de, T>,
{
type Value = SET;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = Self::Value::new(access.size_hint());
while let Some(value) = access.next_element::<DeserializeAsWrap<T, TAs>>()? {
values.replace(value.into_inner());
}
Ok(values)
}
}
#[cfg(feature = "alloc")]
macro_rules! set_impl {
(
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >,
$with_capacity:expr,
$append:ident
) => {
impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty<T $(, $typaram)*>> for SetPreventDuplicates<TAs>
where
TAs: DeserializeAs<'de, T>,
$(T: $tbound1 $(+ $tbound2)*,)*
$($typaram: $bound1 $(+ $bound2)*),*
{
fn deserialize_as<D>(deserializer: D) -> Result<$ty<T $(, $typaram)*>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(SetPreventDuplicatesVisitor::<$ty<T $(, $typaram)*>, T, TAs>(
PhantomData,
))
}
}
impl<'de, T, TAs $(, $typaram)*> DeserializeAs<'de, $ty<T $(, $typaram)*>> for SetLastValueWins<TAs>
where
TAs: DeserializeAs<'de, T>,
$(T: $tbound1 $(+ $tbound2)*,)*
$($typaram: $bound1 $(+ $bound2)*),*
{
fn deserialize_as<D>(deserializer: D) -> Result<$ty<T $(, $typaram)*>, D::Error>
where
D: Deserializer<'de>,
{
deserializer
.deserialize_seq(SetLastValueWinsVisitor::<$ty<T $(, $typaram)*>, T, TAs>(PhantomData))
}
}
}
}
foreach_set_create!(set_impl);
struct MapPreventDuplicatesVisitor<MAP, K, KAs, V, VAs>(PhantomData<(MAP, K, KAs, V, VAs)>);
impl<'de, MAP, K, KAs, V, VAs> Visitor<'de> for MapPreventDuplicatesVisitor<MAP, K, KAs, V, VAs>
where
MAP: PreventDuplicateInsertsMap<K, V>,
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
type Value = MAP;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a map")
}
#[inline]
fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut values = Self::Value::new(access.size_hint());
while let Some((key, value)) =
access.next_entry::<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>()?
{
if !values.insert(key.into_inner(), value.into_inner()) {
return Err(DeError::custom("invalid entry: found duplicate key"));
};
}
Ok(values)
}
}
struct MapFirstKeyWinsVisitor<MAP, K, KAs, V, VAs>(PhantomData<(MAP, K, KAs, V, VAs)>);
impl<'de, MAP, K, KAs, V, VAs> Visitor<'de> for MapFirstKeyWinsVisitor<MAP, K, KAs, V, VAs>
where
MAP: DuplicateInsertsFirstWinsMap<K, V>,
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
{
type Value = MAP;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a map")
}
#[inline]
fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut values = Self::Value::new(access.size_hint());
while let Some((key, value)) =
access.next_entry::<DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>>()?
{
values.insert(key.into_inner(), value.into_inner());
}
Ok(values)
}
}
#[cfg(feature = "alloc")]
macro_rules! map_impl {
(
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$with_capacity:expr
) => {
impl<'de, K, V, KAs, VAs $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>>
for MapPreventDuplicates<KAs, VAs>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
$(K: $kbound1 $(+ $kbound2)*,)*
$($typaram: $bound1 $(+ $bound2)*),*
{
fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(MapPreventDuplicatesVisitor::<
$ty<K, V $(, $typaram)*>,
K,
KAs,
V,
VAs,
>(PhantomData))
}
}
impl<'de, K, V, KAs, VAs $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>>
for MapFirstKeyWins<KAs, VAs>
where
KAs: DeserializeAs<'de, K>,
VAs: DeserializeAs<'de, V>,
$(K: $kbound1 $(+ $kbound2)*,)*
$($typaram: $bound1 $(+ $bound2)*),*
{
fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(MapFirstKeyWinsVisitor::<$ty<K, V $(, $typaram)*>, K, KAs, V, VAs>(
PhantomData,
))
}
}
};
}
foreach_map_create!(map_impl);

1253
third_party/rust/serde_with/src/de/impls.rs поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,85 +0,0 @@
use super::*;
use core::fmt;
use serde::de::*;
macro_rules! array_impl {
($len:literal $($idx:tt)*) => {
impl<'de, T, As> DeserializeAs<'de, [T; $len]> for [As; $len]
where
As: DeserializeAs<'de, T>,
{
fn deserialize_as<D>(deserializer: D) -> Result<[T; $len], D::Error>
where
D: Deserializer<'de>,
{
struct ArrayVisitor<T>(PhantomData<T>);
impl<'de, T, As> Visitor<'de>
for ArrayVisitor<DeserializeAsWrap<T, As>>
where
As: DeserializeAs<'de, T>,
{
type Value = [T; $len];
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(concat!("an array of size ", $len))
}
#[allow(non_snake_case)]
// Because of 0-size arrays
#[allow(unused_variables, unused_mut)]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
Ok([$(
match seq.next_element::<DeserializeAsWrap<T, As>>()? {
Some(value) => value.into_inner(),
None => return Err(Error::invalid_length($idx, &self)),
},
)*])
}
}
deserializer.deserialize_tuple(
$len,
ArrayVisitor::<DeserializeAsWrap<T, As>>(PhantomData),
)
}
}
};
}
array_impl!(0);
array_impl!(1 0);
array_impl!(2 0 1);
array_impl!(3 0 1 2);
array_impl!(4 0 1 2 3);
array_impl!(5 0 1 2 3 4);
array_impl!(6 0 1 2 3 4 5);
array_impl!(7 0 1 2 3 4 5 6);
array_impl!(8 0 1 2 3 4 5 6 7);
array_impl!(9 0 1 2 3 4 5 6 7 8);
array_impl!(10 0 1 2 3 4 5 6 7 8 9);
array_impl!(11 0 1 2 3 4 5 6 7 8 9 10);
array_impl!(12 0 1 2 3 4 5 6 7 8 9 10 11);
array_impl!(13 0 1 2 3 4 5 6 7 8 9 10 11 12);
array_impl!(14 0 1 2 3 4 5 6 7 8 9 10 11 12 13);
array_impl!(15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14);
array_impl!(16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15);
array_impl!(17 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
array_impl!(18 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17);
array_impl!(19 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18);
array_impl!(20 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19);
array_impl!(21 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20);
array_impl!(22 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21);
array_impl!(23 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22);
array_impl!(24 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23);
array_impl!(25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24);
array_impl!(26 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25);
array_impl!(27 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26);
array_impl!(28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27);
array_impl!(29 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28);
array_impl!(30 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29);
array_impl!(31 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30);
array_impl!(32 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31);

27
third_party/rust/serde_with/src/de/mod.rs поставляемый
Просмотреть файл

@ -7,15 +7,16 @@
//!
//! [user guide]: crate::guide
mod const_arrays;
#[cfg(feature = "alloc")]
mod duplicates;
mod impls;
use super::*;
use crate::prelude::*;
/// A **data structure** that can be deserialized from any data format supported by Serde, analogue to [`Deserialize`].
///
/// The trait is analogue to the [`serde::Deserialize`][`Deserialize`] trait, with the same meaning of input and output arguments.
/// It can and should the implemented using the same code structure as the [`Deserialize`] trait.
/// It can and should be implemented using the same code structure as the [`Deserialize`] trait.
/// As such, the same advice for [implementing `Deserialize`][impl-deserialize] applies here.
///
/// # Differences to [`Deserialize`]
@ -74,7 +75,7 @@ use super::*;
/// # #[cfg(all(feature = "macros"))] {
/// # use serde::Deserialize;
/// # use serde::de::Error;
/// # use serde_with::DeserializeAs;
/// # use serde_with::{serde_as, DeserializeAs};
/// # use std::str::FromStr;
/// # use std::fmt::Display;
/// struct DisplayFromStr;
@ -93,7 +94,7 @@ use super::*;
/// }
/// }
/// #
/// # #[serde_with::serde_as]
/// # #[serde_as]
/// # #[derive(serde::Deserialize)]
/// # struct S (#[serde_as(as = "DisplayFromStr")] bool);
/// #
@ -114,7 +115,6 @@ pub trait DeserializeAs<'de, T>: Sized {
}
/// Helper type to implement [`DeserializeAs`] for container-like types.
#[derive(Debug)]
pub struct DeserializeAsWrap<T, U> {
value: T,
marker: PhantomData<U>,
@ -141,3 +141,18 @@ where
})
}
}
impl<T: ?Sized> As<T> {
/// Deserialize type `T` using [`DeserializeAs`][]
///
/// The function signature is compatible with [serde's with-annotation][with-annotation].
///
/// [with-annotation]: https://serde.rs/field-attrs.html#with
pub fn deserialize<'de, D, I>(deserializer: D) -> Result<I, D::Error>
where
T: DeserializeAs<'de, I>,
D: Deserializer<'de>,
{
T::deserialize_as(deserializer)
}
}

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

@ -1,8 +1,6 @@
use alloc::collections::{BTreeMap, BTreeSet};
use core::hash::{BuildHasher, Hash};
#[cfg(feature = "indexmap")]
use indexmap_crate::{IndexMap, IndexSet};
use std::collections::{HashMap, HashSet};
use crate::prelude::*;
#[cfg(feature = "indexmap_1")]
use indexmap_1::{IndexMap, IndexSet};
pub trait PreventDuplicateInsertsSet<T> {
fn new(size_hint: Option<usize>) -> Self;
@ -18,6 +16,7 @@ pub trait PreventDuplicateInsertsMap<K, V> {
fn insert(&mut self, key: K, value: V) -> bool;
}
#[cfg(feature = "std")]
impl<T, S> PreventDuplicateInsertsSet<T> for HashSet<T, S>
where
T: Eq + Hash,
@ -37,7 +36,7 @@ where
}
}
#[cfg(feature = "indexmap")]
#[cfg(feature = "indexmap_1")]
impl<T, S> PreventDuplicateInsertsSet<T> for IndexSet<T, S>
where
T: Eq + Hash,
@ -72,6 +71,7 @@ where
}
}
#[cfg(feature = "std")]
impl<K, V, S> PreventDuplicateInsertsMap<K, V> for HashMap<K, V, S>
where
K: Eq + Hash,
@ -91,7 +91,7 @@ where
}
}
#[cfg(feature = "indexmap")]
#[cfg(feature = "indexmap_1")]
impl<K, V, S> PreventDuplicateInsertsMap<K, V> for IndexMap<K, V, S>
where
K: Eq + Hash,

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

@ -1,16 +1,6 @@
use alloc::collections::{BTreeMap, BTreeSet};
use core::hash::{BuildHasher, Hash};
#[cfg(feature = "indexmap")]
use indexmap_crate::IndexMap;
use std::collections::{HashMap, HashSet};
#[deprecated = "This is serde's default behavior."]
pub trait DuplicateInsertsFirstWinsSet<T> {
fn new(size_hint: Option<usize>) -> Self;
/// Insert the value into the set, if there is not already an existing value
fn insert(&mut self, value: T);
}
use crate::prelude::*;
#[cfg(feature = "indexmap_1")]
use indexmap_1::IndexMap;
pub trait DuplicateInsertsFirstWinsMap<K, V> {
fn new(size_hint: Option<usize>) -> Self;
@ -19,44 +9,7 @@ pub trait DuplicateInsertsFirstWinsMap<K, V> {
fn insert(&mut self, key: K, value: V);
}
#[allow(deprecated)]
impl<T, S> DuplicateInsertsFirstWinsSet<T> for HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher + Default,
{
#[inline]
fn new(size_hint: Option<usize>) -> Self {
match size_hint {
Some(size) => Self::with_capacity_and_hasher(size, S::default()),
None => Self::with_hasher(S::default()),
}
}
#[inline]
fn insert(&mut self, value: T) {
// Hashset already fulfils the contract and always keeps the first value
self.insert(value);
}
}
#[allow(deprecated)]
impl<T> DuplicateInsertsFirstWinsSet<T> for BTreeSet<T>
where
T: Ord,
{
#[inline]
fn new(_size_hint: Option<usize>) -> Self {
Self::new()
}
#[inline]
fn insert(&mut self, value: T) {
// BTreeSet already fulfils the contract and always keeps the first value
self.insert(value);
}
}
#[cfg(feature = "std")]
impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for HashMap<K, V, S>
where
K: Eq + Hash,
@ -84,7 +37,7 @@ where
}
}
#[cfg(feature = "indexmap")]
#[cfg(feature = "indexmap_1")]
impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for IndexMap<K, V, S>
where
K: Eq + Hash,
@ -100,7 +53,7 @@ where
#[inline]
fn insert(&mut self, key: K, value: V) {
use indexmap_crate::map::Entry;
use indexmap_1::map::Entry;
match self.entry(key) {
// we want to keep the first value, so do nothing

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

@ -1,8 +1,6 @@
use alloc::collections::BTreeSet;
use core::hash::{BuildHasher, Hash};
#[cfg(feature = "indexmap")]
use indexmap_crate::IndexSet;
use std::collections::HashSet;
use crate::prelude::*;
#[cfg(feature = "indexmap_1")]
use indexmap_1::IndexSet;
pub trait DuplicateInsertsLastWinsSet<T> {
fn new(size_hint: Option<usize>) -> Self;
@ -11,6 +9,7 @@ pub trait DuplicateInsertsLastWinsSet<T> {
fn replace(&mut self, value: T);
}
#[cfg(feature = "std")]
impl<T, S> DuplicateInsertsLastWinsSet<T> for HashSet<T, S>
where
T: Eq + Hash,
@ -31,7 +30,7 @@ where
}
}
#[cfg(feature = "indexmap")]
#[cfg(feature = "indexmap_1")]
impl<T, S> DuplicateInsertsLastWinsSet<T> for IndexSet<T, S>
where
T: Eq + Hash,

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

@ -2,9 +2,8 @@ mod error_on_duplicate;
mod first_value_wins;
mod last_value_wins;
#[allow(deprecated)]
pub use self::{
error_on_duplicate::{PreventDuplicateInsertsMap, PreventDuplicateInsertsSet},
first_value_wins::{DuplicateInsertsFirstWinsMap, DuplicateInsertsFirstWinsSet},
first_value_wins::DuplicateInsertsFirstWinsMap,
last_value_wins::DuplicateInsertsLastWinsSet,
};

205
third_party/rust/serde_with/src/enum_map.rs поставляемый
Просмотреть файл

@ -1,14 +1,6 @@
use crate::{
content::ser::{Content, ContentSerializer},
DeserializeAs, SerializeAs,
};
use alloc::{string::ToString, vec::Vec};
use core::{fmt, marker::PhantomData};
use serde::{
de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},
ser,
ser::{Impossible, SerializeMap, SerializeSeq, SerializeStructVariant, SerializeTupleVariant},
Deserialize, Deserializer, Serialize, Serializer,
prelude::*,
};
/// Represent a list of enum values as a map.
@ -27,7 +19,7 @@ use serde::{
/// ```rust
/// # #[cfg(feature = "macros")] {
/// # use serde::{Deserialize, Serialize};
/// use serde_with::EnumMap;
/// use serde_with::{serde_as, EnumMap};
///
/// # #[derive(Debug, Clone, PartialEq, Eq)]
/// #[derive(Serialize, Deserialize)]
@ -43,7 +35,7 @@ use serde::{
/// },
/// }
///
/// #[serde_with::serde_as]
/// #[serde_as]
/// # #[derive(Debug, Clone, PartialEq, Eq)]
/// #[derive(Serialize, Deserialize)]
/// struct VecEnumValues (
@ -105,7 +97,7 @@ use serde::{
/// ```
/// # #[cfg(feature = "macros")] {
/// # use serde::{Deserialize, Serialize};
/// use serde_with::EnumMap;
/// use serde_with::{serde_as, EnumMap};
///
/// # #[derive(Debug, Clone, PartialEq, Eq)]
/// #[derive(Serialize, Deserialize)]
@ -115,7 +107,7 @@ use serde::{
/// Unit,
/// }
///
/// #[serde_with::serde_as]
/// #[serde_as]
/// # #[derive(Debug, Clone, PartialEq, Eq)]
/// #[derive(Serialize, Deserialize)]
/// struct VecEnumValues {
@ -139,17 +131,18 @@ use serde::{
/// // into this XML document
/// // Duplicate keys are emitted for identical enum variants.
/// let expected = r#"
/// <?xml version="1.0" encoding="UTF-8"?>
/// <VecEnumValues>
/// <vec>
/// <Int>123</Int>
/// <String>FooBar</String>
/// <Int>456</Int>
/// <String>XXX</String>
/// <Unit></Unit>
/// <Unit />
/// </vec>
/// </VecEnumValues>"#
/// // Remove whitespace
/// .replace(' ', "")
/// .replace(" ", "")
/// .replace('\n', "");
///
/// // Both serialization and deserialization work flawlessly.
@ -159,7 +152,6 @@ use serde::{
/// assert_eq!(values, deserialized);
/// # }
/// ```
#[derive(Debug, Copy, Clone)]
pub struct EnumMap;
impl<T> SerializeAs<Vec<T>> for EnumMap
@ -182,7 +174,10 @@ where
where
D: Deserializer<'de>,
{
struct EnumMapVisitor<T>(PhantomData<T>);
struct EnumMapVisitor<T> {
is_human_readable: bool,
phantom: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for EnumMapVisitor<T>
where
@ -191,15 +186,22 @@ where
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a map or enum values")
write!(formatter, "a map of enum values")
}
fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
Vec::deserialize(SeqDeserializer(map))
Vec::deserialize(SeqDeserializer {
delegate: map,
is_human_readable: self.is_human_readable,
})
}
}
deserializer.deserialize_map(EnumMapVisitor(PhantomData))
let is_human_readable = deserializer.is_human_readable();
deserializer.deserialize_map(EnumMapVisitor {
is_human_readable,
phantom: PhantomData,
})
}
}
@ -228,87 +230,91 @@ where
type SerializeStruct = Impossible<S::Ok, S::Error>;
type SerializeStructVariant = Impossible<S::Ok, S::Error>;
fn is_human_readable(&self) -> bool {
self.0.is_human_readable()
}
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit_variant(
@ -317,7 +323,7 @@ where
_variant_index: u32,
_variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_newtype_struct<T: ?Sized>(
@ -328,7 +334,7 @@ where
where
T: Serialize,
{
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_newtype_variant<T: ?Sized>(
@ -341,7 +347,7 @@ where
where
T: Serialize,
{
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
@ -355,7 +361,7 @@ where
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_tuple_struct(
@ -363,7 +369,7 @@ where
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_tuple_variant(
@ -373,11 +379,11 @@ where
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_struct(
@ -385,7 +391,7 @@ where
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_struct_variant(
@ -395,13 +401,13 @@ where
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
}
/// Serialize a single element but turn the sequence into a map logic.
///
/// It uses [`SerializeEnumAsMapElement`] for the map element serialization.
/// It uses [`EnumAsMapElementSerializer`] for the map element serialization.
///
/// The [`Serializer`] implementation handles all the `serialize_*_variant` functions and defers to [`SerializeVariant`] for the more complicated tuple and struct variants.
struct SerializeSeqElement<M> {
@ -452,87 +458,91 @@ where
type SerializeStruct = Impossible<Self::Ok, Self::Error>;
type SerializeStructVariant = SerializeVariant<'a, M>;
fn is_human_readable(&self) -> bool {
self.is_human_readable
}
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_unit_variant(
@ -553,7 +563,7 @@ where
where
T: Serialize,
{
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_newtype_variant<T: ?Sized>(
@ -571,11 +581,11 @@ where
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_tuple_struct(
@ -583,7 +593,7 @@ where
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_tuple_variant(
@ -602,7 +612,7 @@ where
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_struct(
@ -610,7 +620,7 @@ where
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Err(ser::Error::custom("wrong type for EnumMap"))
Err(SerError::custom("wrong type for EnumMap"))
}
fn serialize_struct_variant(
@ -698,7 +708,10 @@ where
/// Deserialize the sequence of enum instances.
///
/// The main [`Deserializer`] implementation handles the outer sequence (e.g., `Vec`), while the [`SeqAccess`] implementation is responsible for the inner elements.
struct SeqDeserializer<M>(M);
struct SeqDeserializer<M> {
delegate: M,
is_human_readable: bool,
}
impl<'de, M> Deserializer<'de> for SeqDeserializer<M>
where
@ -706,6 +719,10 @@ where
{
type Error = M::Error;
fn is_human_readable(&self) -> bool {
self.is_human_readable
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
@ -737,7 +754,15 @@ where
where
T: DeserializeSeed<'de>,
{
match seed.deserialize(EnumDeserializer(&mut self.0)) {
// We need to check if the map is done, or if there are still remaining elements.
// But we cannot ask the MapAccess directly.
// The only way is trying to deserialize, but we don't know the type yet.
// So we assume there is a value and try to deserialize it.
// If we later on find out that there is no value, we return a special error value, which we turn into `None`.
match seed.deserialize(EnumDeserializer {
delegate: &mut self.delegate,
is_human_readable: self.is_human_readable,
}) {
Ok(value) => Ok(Some(value)),
Err(err) => {
// Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
@ -751,7 +776,7 @@ where
}
fn size_hint(&self) -> Option<usize> {
self.0.size_hint()
self.delegate.size_hint()
}
}
@ -760,7 +785,10 @@ where
/// The [`Deserializer`] implementation is the starting point, which first calls the [`EnumAccess`] methods.
/// The [`EnumAccess`] is used to deserialize the enum variant type of the enum.
/// The [`VariantAccess`] is used to deserialize the value part of the enum.
struct EnumDeserializer<M>(M);
struct EnumDeserializer<M> {
delegate: M,
is_human_readable: bool,
}
impl<'de, M> Deserializer<'de> for EnumDeserializer<M>
where
@ -768,6 +796,10 @@ where
{
type Error = M::Error;
fn is_human_readable(&self) -> bool {
self.is_human_readable
}
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
@ -805,11 +837,11 @@ where
where
T: DeserializeSeed<'de>,
{
match self.0.next_key_seed(seed)? {
match self.delegate.next_key_seed(seed)? {
Some(key) => Ok((key, self)),
// Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
None => Err(Error::custom(END_OF_MAP_IDENTIFIER)),
None => Err(DeError::custom(END_OF_MAP_IDENTIFIER)),
}
}
}
@ -821,21 +853,22 @@ where
type Error = M::Error;
fn unit_variant(mut self) -> Result<(), Self::Error> {
self.0.next_value()
self.delegate.next_value()
}
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
self.0.next_value_seed(seed)
self.delegate.next_value_seed(seed)
}
fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.0.next_value_seed(SeedTupleVariant { len, visitor })
self.delegate
.next_value_seed(SeedTupleVariant { len, visitor })
}
fn struct_variant<V>(
@ -846,7 +879,7 @@ where
where
V: Visitor<'de>,
{
self.0.next_value_seed(SeedStructVariant { visitor })
self.delegate.next_value_seed(SeedStructVariant { visitor })
}
}

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

@ -50,17 +50,19 @@
/// ```
#[macro_export]
macro_rules! flattened_maybe {
($fn:ident, $field:literal) => {
fn $fn<'de, T, D>(deserializer: D) -> ::std::result::Result<T, D::Error>
($fn:ident, $field:tt) => {
fn $fn<'de, T, D>(deserializer: D) -> $crate::__private__::Result<T, D::Error>
where
T: $crate::serde::Deserialize<'de>,
D: $crate::serde::Deserializer<'de>,
{
use ::std::{
option::Option::{self, None, Some},
result::Result::{self, Err, Ok},
use $crate::{
__private__::{
Option::{self, None, Some},
Result::{self, Err, Ok},
},
serde,
};
use $crate::serde;
#[derive($crate::serde::Deserialize)]
#[serde(crate = "serde")]

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше