Skip to content

Commit 7a10ee1

Browse files
committed
add an (optional) syn backend
1 parent b0b52a0 commit 7a10ee1

6 files changed

Lines changed: 575 additions & 4 deletions

File tree

.github/workflows/rust.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@ jobs:
6464
command: test
6565
args: --all-features
6666

67+
test_all_backends:
68+
name: TestAll
69+
runs-on: ${{ matrix.config.os }}
70+
strategy:
71+
fail-fast: false
72+
matrix:
73+
config:
74+
- { os: ubuntu-latest, target: 'x86_64-unknown-linux-gnu' }
75+
- { os: macos-latest, target: 'x86_64-apple-darwin' }
76+
backends: ["syn", ""]
77+
78+
steps:
79+
- uses: actions/checkout@v2
80+
- uses: actions-rs/toolchain@v1
81+
with:
82+
toolchain: stable
83+
target: ${{ matrix.config.target }}
84+
override: true
85+
- uses: actions-rs/cargo@v1
86+
with:
87+
command: test
88+
args: --features "debug_asserts, rustc_hash, generated_setters, debug_diffs, serde, nanoserde, ${{ matrix.backends.target }}"
89+
6790
test_serde:
6891
name: TestSerde
6992
runs-on: ${{ matrix.config.os }}

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ structdiff-derive = { path = "derive", version = "=0.7.4" }
1919
"default" = []
2020
"nanoserde" = ["dep:nanoserde", "structdiff-derive/nanoserde"]
2121
"serde" = ["dep:serde", "structdiff-derive/serde"]
22+
"syn" = ["structdiff-derive/syn"]
2223
"debug_diffs" = ["structdiff-derive/debug_diffs"]
2324
"generated_setters" = ["structdiff-derive/generated_setters"]
2425
"rustc_hash" = ["dep:rustc-hash"]

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ For more examples take a look at [integration tests](/tests)
7070
- `debug_diffs` - Derive `Debug` on the generated diff type
7171
- `generated_setters` - Enable generation of setters for struct fields. These setters automatically return a diff if a field's value is changed by the assignment.
7272
- `rustc_hash` - Use the (non-cryptographic) hash implementation from the `rustc-hash` crate instead of the default hasher. Much faster diff generation for collections at the cost of a dependency.
73+
- `syn` - Use a `syn`-based backend for the `Difference` derive macro. This adds the `syn`, `quote`, and `proc-macro2` dependencies, but supports Rust syntax through `syn`'s parser instead of structdiff's zero-dependency derive parser.
7374

7475
### Development status
7576
This is being used actively for my own projects, although it's mostly working now. PRs will be accepted for either more tests or functionality.

derive/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ proc-macro = true
1111

1212
[dependencies]
1313
nanoserde = { version = "^0.1.37", optional = true }
14+
proc-macro2 = { version = "1.0", optional = true }
15+
quote = { version = "1.0", optional = true }
1416
serde = { version = "^1.0.0", optional = true, features = ["derive"] }
17+
syn = { version = "2.0", optional = true, features = ["derive", "full", "parsing"] }
1518

1619
[features]
1720
"default" = []
1821
"nanoserde" = ["dep:nanoserde"]
1922
"serde" = ["dep:serde"]
23+
"syn" = ["dep:proc-macro2", "dep:quote", "dep:syn"]
2024
"debug_diffs" = []
2125
"generated_setters" = []
2226

derive/src/lib.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,36 @@ extern crate proc_macro;
55
mod shared;
66

77
mod difference;
8+
#[cfg(feature = "syn")]
9+
mod syn_backend;
10+
11+
#[cfg(not(feature = "syn"))]
812
use difference::derive_struct_diff_enum;
913

14+
#[cfg(not(feature = "syn"))]
1015
use crate::difference::derive_struct_diff_struct;
1116

17+
#[cfg_attr(feature = "syn", allow(dead_code))]
1218
mod parse;
1319

1420
/// Derive macro generating an impl of the trait `StructDiff`
1521
#[proc_macro_derive(Difference, attributes(difference))]
1622
pub fn derive_struct_diff(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
23+
derive_struct_diff_impl(input)
24+
}
25+
26+
#[cfg(feature = "syn")]
27+
fn derive_struct_diff_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
28+
syn_backend::derive_struct_diff(input)
29+
}
30+
31+
#[cfg(not(feature = "syn"))]
32+
fn derive_struct_diff_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1733
let input = parse::parse_data(input);
1834

19-
let ts = match &input {
35+
match &input {
2036
parse::Data::Struct(struct_) if struct_.named => derive_struct_diff_struct(struct_),
2137
parse::Data::Enum(enum_) => derive_struct_diff_enum(enum_),
2238
_ => unimplemented!("Only structs and enums are supported"),
23-
};
24-
25-
ts
39+
}
2640
}

0 commit comments

Comments
 (0)