mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 10:44:07 +02:00
derive: update to syn2 and structmeta
This commit is contained in:
parent
1042648059
commit
7aacb8a6eb
7 changed files with 332 additions and 86 deletions
104
Cargo.lock
generated
104
Cargo.lock
generated
|
|
@ -50,7 +50,7 @@ dependencies = [
|
||||||
"owo-colors",
|
"owo-colors",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.105",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -172,6 +172,28 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
checksum = "155db5e86c6e45ee456bf32fad5a290ee1f7151c2faca27ea27097568da67d1a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merge"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
|
||||||
|
dependencies = [
|
||||||
|
"merge_derive",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merge_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.105",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
|
@ -199,7 +221,7 @@ dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.105",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -232,19 +254,43 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro-error"
|
||||||
version = "1.0.47"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.105",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
@ -261,6 +307,29 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structmeta"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ad9e09554f0456d67a69c1584c9798ba733a5b50349a6c0d0948710523922d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"structmeta-derive",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structmeta-derive"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.105"
|
version = "1.0.105"
|
||||||
|
|
@ -273,14 +342,14 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn_util"
|
name = "syn"
|
||||||
version = "0.4.2"
|
version = "2.0.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c"
|
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -300,7 +369,7 @@ checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 1.0.105",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -341,12 +410,19 @@ dependencies = [
|
||||||
name = "vbsp-derive"
|
name = "vbsp-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"merge",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"structmeta",
|
||||||
"syn_util",
|
"syn 2.0.39",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zip-lzma"
|
name = "zip-lzma"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ lzma-rs = "0.2.0"
|
||||||
binrw = "0.10.0"
|
binrw = "0.10.0"
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
num_enum = "0.5.7"
|
num_enum = "0.5.7"
|
||||||
vbsp-derive = { path = "derive", version = "0.1.0" }
|
vbsp-derive = { path = "derive", version = "0.1.0", features = ["__vbsp_as_self"] }
|
||||||
cgmath = "0.18.0"
|
cgmath = "0.18.0"
|
||||||
zip = { package = "zip-lzma", version = "0.6.3", default-features = false, features = ["lzma"] }
|
zip = { package = "zip-lzma", version = "0.6.3", default-features = false, features = ["lzma"] }
|
||||||
|
|
||||||
|
|
|
||||||
127
derive/Cargo.lock
generated
127
derive/Cargo.lock
generated
|
|
@ -3,57 +3,148 @@
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "autocfg"
|
||||||
version = "1.0.36"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merge"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10bbef93abb1da61525bbc45eeaff6473a41907d19f8f9aa5168d214e10693e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"merge_derive",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "merge_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "209d075476da2e63b4b29e72a2ef627b840589588e71400a25e3565c4f849d07"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.15"
|
version = "1.0.33"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structmeta"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ad9e09554f0456d67a69c1584c9798ba733a5b50349a6c0d0948710523922d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"structmeta-derive",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "structmeta-derive"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.39",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.86"
|
version = "1.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"unicode-xid",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn_util"
|
name = "syn"
|
||||||
version = "0.4.2"
|
version = "2.0.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6754c4559b79657554e9d8a0d56e65e490c76d382b9c23108364ec4125dea23c"
|
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-ident"
|
||||||
version = "0.2.2"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vbsp-derive"
|
name = "vbsp-derive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"merge",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"structmeta",
|
||||||
"syn_util",
|
"syn 2.0.39",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,11 @@ edition = "2021"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
syn = "1.0.82"
|
syn = "2.0.39"
|
||||||
quote = "1.0.10"
|
quote = "1.0.33"
|
||||||
proc-macro2 = "1.0.33"
|
proc-macro2 = "1.0.69"
|
||||||
syn_util = "0.4.2"
|
structmeta = "0.2.0"
|
||||||
|
merge = "0.1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
__vbsp_as_self = []
|
__vbsp_as_self = []
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
use proc_macro2::{Ident, TokenStream};
|
use crate::parse_attrs;
|
||||||
use quote::{quote, ToTokens, TokenStreamExt};
|
use merge::Merge;
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::{quote, quote_spanned, ToTokens, TokenStreamExt};
|
||||||
|
use structmeta::StructMeta;
|
||||||
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
Data, DataEnum, DataStruct, DeriveInput, Field, GenericParam, Path, PathArguments, PathSegment,
|
Data, DataEnum, DataStruct, DeriveInput, Error, Field, GenericParam, Ident, LitStr, Path,
|
||||||
Type, TypePath, Variant,
|
PathArguments, PathSegment, Result, Type, TypePath, Variant,
|
||||||
};
|
};
|
||||||
use syn_util::{contains_attribute, get_attribute_value};
|
|
||||||
|
|
||||||
type Result<T, E = &'static str> = std::result::Result<T, E>;
|
|
||||||
|
|
||||||
pub fn derive_entity(input: DeriveInput) -> Result<proc_macro2::TokenStream> {
|
pub fn derive_entity(input: DeriveInput) -> Result<proc_macro2::TokenStream> {
|
||||||
if input.generics.lifetimes().count() > 1 {
|
if input.generics.lifetimes().count() > 1 {
|
||||||
return Err("Can't derive Entity on structs or entities with more than 1 lifetime");
|
return Err(Error::new(
|
||||||
|
input.generics.span(),
|
||||||
|
"Can't derive Entity on structs or entities with more than 1 lifetime",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let source_lifetime = input
|
let source_lifetime = input
|
||||||
.generics
|
.generics
|
||||||
|
|
@ -18,10 +22,19 @@ pub fn derive_entity(input: DeriveInput) -> Result<proc_macro2::TokenStream> {
|
||||||
.iter()
|
.iter()
|
||||||
.find(|param| matches!(param, GenericParam::Lifetime(_)));
|
.find(|param| matches!(param, GenericParam::Lifetime(_)));
|
||||||
|
|
||||||
|
#[cfg(feature = "__vbsp_as_self")]
|
||||||
|
let crate_name = "crate";
|
||||||
|
#[cfg(not(feature = "__vbsp_as_self"))]
|
||||||
|
let crate_name = "vbsp";
|
||||||
|
let crate_ident = Ident::new(crate_name, input.span());
|
||||||
|
|
||||||
match &input.data {
|
match &input.data {
|
||||||
Data::Struct(data) => derive_entity_struct(&input, data, source_lifetime),
|
Data::Struct(data) => derive_entity_struct(&input, data, source_lifetime, crate_ident),
|
||||||
Data::Enum(data) => derive_entity_enum(&input, data, source_lifetime),
|
Data::Enum(data) => derive_entity_enum(&input, data, source_lifetime, crate_ident),
|
||||||
_ => Err("Can only derive Entity for structs and enums"),
|
_ => Err(Error::new(
|
||||||
|
input.span(),
|
||||||
|
"Can only derive Entity for structs and enums",
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,34 +42,40 @@ fn derive_entity_enum(
|
||||||
input: &DeriveInput,
|
input: &DeriveInput,
|
||||||
data: &DataEnum,
|
data: &DataEnum,
|
||||||
source_lifetime: Option<&GenericParam>,
|
source_lifetime: Option<&GenericParam>,
|
||||||
|
crate_ident: Ident,
|
||||||
) -> Result<proc_macro2::TokenStream> {
|
) -> Result<proc_macro2::TokenStream> {
|
||||||
let variants = data
|
let variants = data
|
||||||
.variants
|
.variants
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|variant| !contains_attribute(&variant.attrs, &["entity", "default"]))
|
|
||||||
.map(EntityVariant::try_from)
|
.map(EntityVariant::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<EntityVariant>>>()?;
|
||||||
|
|
||||||
let default = &data
|
if variants
|
||||||
.variants
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|variant| contains_attribute(&variant.attrs, &["entity", "default"]))
|
.filter(|variant| variant.is_default())
|
||||||
.ok_or("Enum must have one variant with `#[entity(default)]` set")?
|
.count()
|
||||||
.ident;
|
!= 1
|
||||||
|
{
|
||||||
|
return Err(Error::new(
|
||||||
|
data.variants.span(),
|
||||||
|
"Enums must have exactly one variant with `#[entity(default)]` set",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
let lifetime_or_default = LifetimeOrAnonymous(source_lifetime);
|
let lifetime_or_default = LifetimeOrAnonymous(source_lifetime);
|
||||||
|
|
||||||
Ok(quote! {
|
let span = input.span();
|
||||||
impl #impl_generics TryFrom<crate::RawEntity<#lifetime_or_default>> for #name #ty_generics #where_clause {
|
|
||||||
type Error = crate::error::EntityParseError;
|
|
||||||
|
|
||||||
fn try_from(raw: crate::RawEntity<#source_lifetime>) -> Result<Self, Self::Error> {
|
Ok(quote_spanned! {span =>
|
||||||
|
impl #impl_generics TryFrom<#crate_ident::RawEntity<#lifetime_or_default>> for #name #ty_generics #where_clause {
|
||||||
|
type Error = #crate_ident::error::EntityParseError;
|
||||||
|
|
||||||
|
fn try_from(raw: #crate_ident::RawEntity<#source_lifetime>) -> Result<Self, Self::Error> {
|
||||||
let class = raw.prop("classname")?;
|
let class = raw.prop("classname")?;
|
||||||
Ok(match class {
|
Ok(match class {
|
||||||
#(#variants)*
|
#(#variants)*
|
||||||
_ => Self::#default(raw),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -67,22 +86,23 @@ fn derive_entity_struct(
|
||||||
input: &DeriveInput,
|
input: &DeriveInput,
|
||||||
data: &DataStruct,
|
data: &DataStruct,
|
||||||
source_lifetime: Option<&GenericParam>,
|
source_lifetime: Option<&GenericParam>,
|
||||||
|
crate_ident: Ident,
|
||||||
) -> Result<proc_macro2::TokenStream> {
|
) -> Result<proc_macro2::TokenStream> {
|
||||||
let fields = data
|
let fields = data
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(EntityField::try_from)
|
.map(EntityField::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>>>()?;
|
||||||
|
|
||||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
let lifetime_or_default = LifetimeOrAnonymous(source_lifetime);
|
let lifetime_or_default = LifetimeOrAnonymous(source_lifetime);
|
||||||
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
impl #impl_generics TryFrom<crate::RawEntity<#lifetime_or_default>> for #name #ty_generics #where_clause {
|
impl #impl_generics TryFrom<#crate_ident::RawEntity<#lifetime_or_default>> for #name #ty_generics #where_clause {
|
||||||
type Error = crate::error::EntityParseError;
|
type Error = #crate_ident::error::EntityParseError;
|
||||||
|
|
||||||
fn try_from(raw: crate::RawEntity<#source_lifetime>) -> Result<Self, Self::Error> {
|
fn try_from(raw: #crate_ident::RawEntity<#source_lifetime>) -> Result<Self, Self::Error> {
|
||||||
Ok(#name {
|
Ok(#name {
|
||||||
#(#fields)*
|
#(#fields)*
|
||||||
})
|
})
|
||||||
|
|
@ -102,6 +122,19 @@ impl ToTokens for LifetimeOrAnonymous<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, StructMeta, Merge)]
|
||||||
|
struct EntityFieldAttrs {
|
||||||
|
name: Option<LitStr>,
|
||||||
|
#[merge(strategy = merge::bool::overwrite_false)]
|
||||||
|
default: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EntityFieldAttrs {
|
||||||
|
pub fn name(&self) -> Option<String> {
|
||||||
|
self.name.as_ref().map(LitStr::value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct EntityField<'a> {
|
struct EntityField<'a> {
|
||||||
field: &'a Ident,
|
field: &'a Ident,
|
||||||
name: String,
|
name: String,
|
||||||
|
|
@ -109,20 +142,19 @@ struct EntityField<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a Field> for EntityField<'a> {
|
impl<'a> TryFrom<&'a Field> for EntityField<'a> {
|
||||||
type Error = &'static str;
|
type Error = syn::Error;
|
||||||
|
|
||||||
fn try_from(field: &'a Field) -> std::result::Result<Self, Self::Error> {
|
fn try_from(field: &'a Field) -> Result<Self> {
|
||||||
let ident = &field
|
let attrs: EntityFieldAttrs = parse_attrs(&field.attrs)?;
|
||||||
.ident
|
let ident = &field.ident.as_ref().ok_or(Error::new(
|
||||||
.as_ref()
|
field.span(),
|
||||||
.ok_or("Can't derive Entity on structs with unnamed fields")?;
|
"Can't derive Entity on structs with unnamed fields",
|
||||||
let name = get_attribute_value(&field.attrs, &["entity", "name"])
|
))?;
|
||||||
.unwrap_or_else(|| ident.to_string());
|
let name = attrs.name().unwrap_or_else(|| ident.to_string());
|
||||||
let default = contains_attribute(&field.attrs, &["entity", "default"]);
|
|
||||||
Ok(EntityField {
|
Ok(EntityField {
|
||||||
field: ident,
|
field: ident,
|
||||||
name,
|
name,
|
||||||
default,
|
default: attrs.default,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -140,25 +172,46 @@ impl ToTokens for EntityField<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EntityVariant<'a> {
|
struct EntityVariant<'a> {
|
||||||
name: String,
|
name: NameOrDefault,
|
||||||
variant: &'a Ident,
|
variant: &'a Ident,
|
||||||
ty: &'a Path,
|
ty: &'a Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&'a Variant> for EntityVariant<'a> {
|
impl EntityVariant<'_> {
|
||||||
type Error = &'static str;
|
fn is_default(&self) -> bool {
|
||||||
|
matches!(self.name, NameOrDefault::Default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn try_from(value: &'a Variant) -> std::result::Result<Self, Self::Error> {
|
enum NameOrDefault {
|
||||||
let name = get_attribute_value(&value.attrs, &["entity", "name"]).ok_or(
|
Name(String),
|
||||||
"All variants must have the `#[entity(name)]` or `#[entity(default)]` attribute set",
|
Default,
|
||||||
)?;
|
}
|
||||||
|
|
||||||
|
impl<'a> TryFrom<&'a Variant> for EntityVariant<'a> {
|
||||||
|
type Error = syn::Error;
|
||||||
|
|
||||||
|
fn try_from(value: &'a Variant) -> Result<Self> {
|
||||||
|
let attrs: EntityFieldAttrs = parse_attrs(&value.attrs)?;
|
||||||
|
let name = match attrs.default {
|
||||||
|
true => NameOrDefault::Default,
|
||||||
|
false => NameOrDefault::Name(attrs.name().ok_or_else(||Error::new(value.span(), "All variants must have the `#[entity(name)]` or `#[entity(default)]` attribute set"),) ?)
|
||||||
|
};
|
||||||
if value.fields.len() != 1 {
|
if value.fields.len() != 1 {
|
||||||
return Err("All enum variants must have exactly one field");
|
return Err(Error::new(
|
||||||
|
value.span(),
|
||||||
|
"All enum variants must have exactly one field",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let field = value.fields.iter().next().unwrap();
|
let field = value.fields.iter().next().unwrap();
|
||||||
let path = match &field.ty {
|
let path = match &field.ty {
|
||||||
Type::Path(TypePath { path, .. }) => path,
|
Type::Path(TypePath { path, .. }) => path,
|
||||||
_ => return Err("Variants can only contain plain types"),
|
_ => {
|
||||||
|
return Err(Error::new(
|
||||||
|
field.span(),
|
||||||
|
"Variants can only contain plain types",
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(EntityVariant {
|
Ok(EntityVariant {
|
||||||
name,
|
name,
|
||||||
|
|
@ -184,6 +237,13 @@ impl ToTokens for EntityVariant<'_> {
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
stream.append_all(quote! {#name => Self::#variant(#ty::try_from(raw)?),});
|
match name {
|
||||||
|
NameOrDefault::Default => {
|
||||||
|
stream.append_all(quote! {_ => Self::#variant(#ty::from(raw)),})
|
||||||
|
}
|
||||||
|
NameOrDefault::Name(name) => {
|
||||||
|
stream.append_all(quote! {#name => Self::#variant(#ty::try_from(raw)?),})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use quote::quote;
|
use merge::Merge;
|
||||||
use syn::{parse_macro_input, DeriveInput};
|
use syn::parse::Parse;
|
||||||
|
use syn::{parse_macro_input, Attribute, DeriveInput, Result};
|
||||||
|
|
||||||
mod entity;
|
mod entity;
|
||||||
|
|
||||||
|
|
@ -8,12 +9,21 @@ pub fn derive_entity(input: proc_macro::TokenStream) -> proc_macro::TokenStream
|
||||||
derive_wrapper(input, entity::derive_entity)
|
derive_wrapper(input, entity::derive_entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_wrapper<F: Fn(DeriveInput) -> Result<proc_macro2::TokenStream, &'static str>>(
|
fn derive_wrapper<F: Fn(DeriveInput) -> Result<proc_macro2::TokenStream>>(
|
||||||
input: proc_macro::TokenStream,
|
input: proc_macro::TokenStream,
|
||||||
derive: F,
|
derive: F,
|
||||||
) -> proc_macro::TokenStream {
|
) -> proc_macro::TokenStream {
|
||||||
match derive(parse_macro_input!(input as DeriveInput)) {
|
match derive(parse_macro_input!(input as DeriveInput)) {
|
||||||
Ok(tokens) => tokens.into(),
|
Ok(tokens) => tokens.into(),
|
||||||
Err(e) => quote!(compile_error!(#e)).into(),
|
Err(e) => e.into_compile_error().into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_attrs<T: Parse + Default + Merge>(attrs: &[Attribute]) -> Result<T> {
|
||||||
|
let mut result = T::default();
|
||||||
|
for attr in attrs {
|
||||||
|
let parsed = attr.parse_args()?;
|
||||||
|
result.merge(parsed);
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,14 @@
|
||||||
RUSTC_BOOTSTRAP=1 cargo-fuzz $@
|
RUSTC_BOOTSTRAP=1 cargo-fuzz $@
|
||||||
'';
|
'';
|
||||||
})
|
})
|
||||||
|
(writeShellApplication {
|
||||||
|
name = "cargo-expand";
|
||||||
|
runtimeInputs = [cargo-expand toolchain];
|
||||||
|
text = ''
|
||||||
|
# shellcheck disable=SC2068
|
||||||
|
RUSTC_BOOTSTRAP=1 cargo-expand $@
|
||||||
|
'';
|
||||||
|
})
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
default = mkShell {
|
default = mkShell {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue