Skip to content

refactor: improve macro derive - #318

Merged
jlucaso1 merged 4 commits into
mainfrom
refactor-improve-macro-derive
Mar 11, 2026
Merged

refactor: improve macro derive#318
jlucaso1 merged 4 commits into
mainfrom
refactor-improve-macro-derive

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Mar 11, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor
    • Standardized string-based enum handling and protocol (de)serialization across the codebase for more consistent behavior.
  • Bug Fixes
    • Improved handling of unknown/unsupported enum values so wire-format unknowns are preserved and round-tripped reliably.
  • Chores
    • Consolidated repetitive serialization logic and generation paths to reduce duplication and simplify future maintenance.

@coderabbitai

coderabbitai Bot commented Mar 11, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Centralizes string-based enum parsing and ProtocolNode attribute handling: adds StringEnum support and ParseStringEnum, extends derive macros for string_enum/u64/u32 and fallbacks, and replaces many manual as_str/TryFrom and ProtocolNode impls with derive-based implementations across multiple modules.

Changes

Cohort / File(s) Summary
StringEnum & derive infra
wacore/derive/src/lib.rs, wacore/src/protocol.rs
Adds StringEnum support (including string_fallback, string_default), u64/u32 attr handling, ParseStringEnum trait and parse_string_enum helper; expands macro-generated impls (From/TryFrom/Default/Display) depending on fallback mode.
General enum conversions
src/features/status.rs, wacore/src/iq/contacts.rs, wacore/src/iq/dirty.rs, wacore/src/iq/privacy.rs, wacore/src/iq/usync.rs, wacore/src/types/lid_pn.rs, wacore/src/types/message.rs
Replaced many manual as_str/From/TryFrom impls with crate::StringEnum derive and per-variant #[str = "..."] / #[string_fallback] / #[string_default] attributes; preserves public enum names but changes generated parsing/serialization behavior (fallback handling retained where present).
ProtocolNode derive replacements
wacore/src/ib.rs, wacore/src/iq/blocklist.rs, wacore/src/iq/groups.rs
Removed manual ProtocolNode impls and added #[derive(..., crate::ProtocolNode)] with #[protocol(tag = "...")] and #[attr(...)] annotations; introduced define_group_participant_iq macro to generate Add/Remove/Promote/Demote IQ types and IqSpec implementations.
IQ field attribute updates
wacore/src/iq/blocklist.rs, wacore/src/iq/groups.rs
Field-level protocol attributes added (e.g., jid, action with string_enum, timestamp as u64), and unnecessary manual helpers/imports removed.
Message-related enums & tests
wacore/src/types/message.rs
AddressingMode and EditAttribute converted to StringEnum derive; Unknown/Unknown-like variants now preserved via fallback and tests updated to reflect round-trip/wire-format behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through enums, strings in tow,
Turned matches to derives, tidy and slow,
Fallbacks saved secrets, defaults stand true,
Macros stitched patterns, neat and new,
A rabbit hums—code compiled, off we go! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title 'refactor: improve macro derive' is vague and generic, using non-descriptive terms that fail to convey meaningful information about the substantial changeset. Use a more specific title that highlights the primary change, such as 'refactor: migrate string enums to StringEnum derive macro' or 'refactor: consolidate protocol serialization via macro expansion'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor-improve-macro-derive

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Mar 11, 2026

Copy link
Copy Markdown

🐰 Bencher Report

Branchrefactor-improve-macro-derive
Testbedubuntu-latest

🚨 1 Alert

BenchmarkMeasure
Units
ViewBenchmark Result
(Result Δ%)
Upper Boundary
(Limit %)
binary_benchmark::unpack_group::bench_unpack_compressedInstructions
instructions x 1e3
📈 plot
🚷 threshold
🚨 alert (🔔)
556.09 x 1e3
(+5.59%)Baseline: 526.66 x 1e3
552.99 x 1e3
(100.56%)

Click to view all benchmark results
BenchmarkInstructionsBenchmark Result
instructions
(Result Δ%)
Upper Boundary
instructions
(Limit %)
binary_benchmark::attr_parser_group::bench_attr_parser attr_lookup:setup_attr_marshaled()📈 view plot
🚷 view threshold
6,124.00
(-11.93%)Baseline: 6,953.28
7,300.94
(83.88%)
binary_benchmark::child_iteration_group::bench_get_children_by_tag📈 view plot
🚷 view threshold
850,787.00
(+0.00%)Baseline: 850,766.18
893,304.49
(95.24%)
binary_benchmark::jid_optimization_group::bench_jid_to_owned_access jid_access:setup_jid_heavy_marshaled()📈 view plot
🚷 view threshold
22,227.00
(-5.41%)Baseline: 23,498.08
24,672.99
(90.09%)
binary_benchmark::marshal_group::bench_marshal_allocating📈 view plot
🚷 view threshold
119,186.00
(-9.70%)Baseline: 131,988.51
138,587.93
(86.00%)
binary_benchmark::marshal_group::bench_marshal_auto_allocating📈 view plot
🚷 view threshold
119,214.00
(-0.00%)Baseline: 119,216.19
125,177.00
(95.24%)
binary_benchmark::marshal_group::bench_marshal_auto_huge_bytes_allocating📈 view plot
🚷 view threshold
534,031.00
(+0.00%)Baseline: 534,030.74
560,732.28
(95.24%)
binary_benchmark::marshal_group::bench_marshal_auto_long_string📈 view plot
🚷 view threshold
17,350.00
(0.00%)Baseline: 17,350.00
18,217.50
(95.24%)
binary_benchmark::marshal_group::bench_marshal_auto_many_children_allocating📈 view plot
🚷 view threshold
17,133,858.00
(-0.00%)Baseline: 17,134,037.42
17,990,739.29
(95.24%)
binary_benchmark::marshal_group::bench_marshal_exact_allocating📈 view plot
🚷 view threshold
176,687.00
(-0.00%)Baseline: 176,689.19
185,523.65
(95.24%)
binary_benchmark::marshal_group::bench_marshal_exact_huge_bytes_allocating📈 view plot
🚷 view threshold
535,444.00
(+0.00%)Baseline: 535,443.74
562,215.93
(95.24%)
binary_benchmark::marshal_group::bench_marshal_exact_long_string📈 view plot
🚷 view threshold
19,404.00
(0.00%)Baseline: 19,404.00
20,374.20
(95.24%)
binary_benchmark::marshal_group::bench_marshal_exact_many_children_allocating📈 view plot
🚷 view threshold
42,766,353.00
(-0.00%)Baseline: 42,766,709.39
44,905,044.86
(95.24%)
binary_benchmark::marshal_group::bench_marshal_huge_bytes_allocating📈 view plot
🚷 view threshold
534,470.00
(+0.00%)Baseline: 534,469.74
561,193.23
(95.24%)
binary_benchmark::marshal_group::bench_marshal_long_string📈 view plot
🚷 view threshold
17,323.00
(-6.22%)Baseline: 18,472.38
19,395.99
(89.31%)
binary_benchmark::marshal_group::bench_marshal_many_children_allocating📈 view plot
🚷 view threshold
17,134,657.00
(-0.00%)Baseline: 17,134,839.32
17,991,581.29
(95.24%)
binary_benchmark::marshal_group::bench_marshal_reusing_buffer📈 view plot
🚷 view threshold
129,087.00
(-4.08%)Baseline: 134,579.33
141,308.29
(91.35%)
binary_benchmark::marshal_group::bench_marshal_reusing_buffer_vec_writer📈 view plot
🚷 view threshold
119,286.00
(-0.00%)Baseline: 119,288.19
125,252.60
(95.24%)
binary_benchmark::roundtrip_group::bench_roundtrip large:setup_large_marshaled()📈 view plot
🚷 view threshold
93,716.00
(-8.05%)Baseline: 101,920.90
107,016.94
(87.57%)
binary_benchmark::roundtrip_group::bench_roundtrip small:setup_small_marshaled()📈 view plot
🚷 view threshold
7,249.00
(-10.03%)Baseline: 8,056.87
8,459.71
(85.69%)
binary_benchmark::roundtrip_group::bench_roundtrip_auto large:setup_large_marshaled()📈 view plot
🚷 view threshold
93,747.00
(+0.00%)Baseline: 93,744.10
98,431.30
(95.24%)
binary_benchmark::roundtrip_group::bench_roundtrip_auto small:setup_small_marshaled()📈 view plot
🚷 view threshold
7,272.00
(0.00%)Baseline: 7,272.00
7,635.60
(95.24%)
binary_benchmark::roundtrip_group::bench_roundtrip_exact large:setup_large_marshaled()📈 view plot
🚷 view threshold
109,532.00
(+0.00%)Baseline: 109,529.10
115,005.55
(95.24%)
binary_benchmark::roundtrip_group::bench_roundtrip_exact small:setup_small_marshaled()📈 view plot
🚷 view threshold
8,784.00
(0.00%)Baseline: 8,784.00
9,223.20
(95.24%)
binary_benchmark::unmarshal_group::bench_unmarshal large:setup_large_marshaled()📈 view plot
🚷 view threshold
44,794.00
(-7.16%)Baseline: 48,248.34
50,660.75
(88.42%)
binary_benchmark::unmarshal_group::bench_unmarshal small:setup_small_marshaled()📈 view plot
🚷 view threshold
2,588.00
(-13.62%)Baseline: 2,996.18
3,145.99
(82.26%)
binary_benchmark::unpack_group::bench_unpack_compressed📈 view plot
🚷 view threshold
🚨 view alert (🔔)
556,092.00
(+5.59%)Baseline: 526,655.94
552,988.74
(100.56%)

binary_benchmark::unpack_group::bench_unpack_uncompressed📈 view plot
🚷 view threshold
771.00
(-0.66%)Baseline: 776.12
814.93
(94.61%)
libsignal_benchmark::conversation_group::bench_full_dm_conversation full:setup_conversation_data()📈 view plot
🚷 view threshold
27,754,442.00
(+0.06%)Baseline: 27,738,959.51
29,125,907.48
(95.29%)
libsignal_benchmark::dm_group::bench_dm_decrypt_first_message decrypt_prekey:setup_dm_with_first_message()📈 view plot
🚷 view threshold
5,540,322.00
(-0.29%)Baseline: 5,556,228.96
5,834,040.40
(94.97%)
libsignal_benchmark::dm_group::bench_dm_encrypt_first_message first_msg:setup_dm_session()📈 view plot
🚷 view threshold
178,094.00
(+0.05%)Baseline: 178,009.40
186,909.87
(95.28%)
libsignal_benchmark::dm_group::bench_dm_encrypt_subsequent_message subsequent:setup_established_dm_session()📈 view plot
🚷 view threshold
178,905.00
(+0.05%)Baseline: 178,821.65
187,762.73
(95.28%)
libsignal_benchmark::dm_group::bench_dm_session_establishment setup:setup_dm_users()📈 view plot
🚷 view threshold
17,277,599.00
(-0.05%)Baseline: 17,286,494.91
18,150,819.66
(95.19%)
libsignal_benchmark::group_messaging_group::bench_group_create_distribution_message create:setup_group_sender()📈 view plot
🚷 view threshold
295,884.00
(+0.02%)Baseline: 295,825.14
310,616.40
(95.26%)
libsignal_benchmark::group_messaging_group::bench_group_decrypt_message decrypt:setup_group_with_encrypted_message()📈 view plot
🚷 view threshold
12,695,623.00
(+0.73%)Baseline: 12,604,062.14
13,234,265.25
(95.93%)
libsignal_benchmark::group_messaging_group::bench_group_encrypt_message encrypt:setup_group_with_distribution()📈 view plot
🚷 view threshold
715,609.00
(-0.02%)Baseline: 715,778.54
751,567.47
(95.22%)
libsignal_benchmark::session_optimization_group::bench_decrypt_with_previous_session previous_session:setup_with_archived_sessions()📈 view plot
🚷 view threshold
41,823.00
(+0.05%)Baseline: 41,802.32
43,892.44
(95.29%)
libsignal_benchmark::session_optimization_group::bench_message_key_eviction eviction:setup_message_key_eviction()📈 view plot
🚷 view threshold
15,561,842.00
(+0.00%)Baseline: 15,561,589.30
16,339,668.77
(95.24%)
libsignal_benchmark::session_optimization_group::bench_out_of_order_decryption out_of_order:setup_out_of_order_messages()📈 view plot
🚷 view threshold
5,504,859.00
(-0.21%)Baseline: 5,516,214.46
5,792,025.18
(95.04%)
libsignal_benchmark::session_optimization_group::bench_promote_matching_session promote:setup_promote_matching_session()📈 view plot
🚷 view threshold
956,774.00
(-0.41%)Baseline: 960,667.79
1,008,701.18
(94.85%)
libsignal_benchmark::signature_group::bench_key_generation keygen📈 view plot
🚷 view threshold
2,822,723.00
(-0.01%)Baseline: 2,823,003.52
2,964,153.70
(95.23%)
libsignal_benchmark::signature_group::bench_signature_creation sign:setup_keypair_with_message()📈 view plot
🚷 view threshold
3,444,364.00
(-2.01%)Baseline: 3,514,890.03
3,690,634.53
(93.33%)
libsignal_benchmark::signature_group::bench_signature_verification verify:setup_keypair_with_message()📈 view plot
🚷 view threshold
125,713,025.00
(+0.16%)Baseline: 125,517,106.48
131,792,961.80
(95.39%)
reporting_token_benchmark::content_extraction_group::bench_content_extraction extended:setup_extended_message()📈 view plot
🚷 view threshold
11,812.00
(+0.18%)Baseline: 11,790.89
12,380.43
(95.41%)
reporting_token_benchmark::content_extraction_group::bench_content_extraction simple:setup_simple_message()📈 view plot
🚷 view threshold
3,825.00
(+0.07%)Baseline: 3,822.51
4,013.63
(95.30%)
reporting_token_benchmark::full_generation_group::bench_full_token_generation extended:setup_full_gen_extended()📈 view plot
🚷 view threshold
87,972.00
(+0.00%)Baseline: 87,970.88
92,369.42
(95.24%)
reporting_token_benchmark::full_generation_group::bench_full_token_generation simple:setup_full_gen_simple()📈 view plot
🚷 view threshold
80,008.00
(-0.02%)Baseline: 80,025.50
84,026.77
(95.22%)
reporting_token_benchmark::key_derivation_group::bench_key_derivation📈 view plot
🚷 view threshold
51,011.00
(-0.03%)Baseline: 51,025.80
53,577.08
(95.21%)
reporting_token_benchmark::message_encoding_group::bench_message_encoding extended:setup_extended_message()📈 view plot
🚷 view threshold
5,762.00
(+0.40%)Baseline: 5,739.20
6,026.17
(95.62%)
reporting_token_benchmark::message_encoding_group::bench_message_encoding simple:setup_simple_message()📈 view plot
🚷 view threshold
2,122.00
(+0.28%)Baseline: 2,116.07
2,221.88
(95.50%)
reporting_token_benchmark::token_calculation_group::bench_token_calculation📈 view plot
🚷 view threshold
21,920.00
(+0.03%)Baseline: 21,913.52
23,009.19
(95.27%)
🐰 View full continuous benchmarking report in Bencher

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
wacore/derive/src/lib.rs (2)

725-790: ⚠️ Potential issue | 🟠 Major

Fix fallback enum validation and Default impl generation in StringEnum macro.

Two edge cases generate invalid code:

  1. Fallback-only enum (no regular variants): Line 741 accesses variant_infos[0] without checking if the collection is empty. The guard on line 733 only triggers if both variant_infos.is_empty() && fallback_variant.is_none() are true, allowing a fallback-only enum to pass and panic on indexing.

  2. #[string_default] on fallback variant: If the fallback variant is marked as default, line 802 generates #name::#default_variant`` (e.g., Enum::Other), which requires a `String` argument but none is provided. This produces a compile error.

Neither issue currently affects enums in the codebase (all existing fallback enums have ≥2 regular variants and none mark the fallback as default), but the macro should either reject these patterns with a clear syn::Error or generate valid code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wacore/derive/src/lib.rs` around lines 725 - 790, The macro must reject
unsupported fallback-only enums and cases where the fallback variant is marked
#[string_default]; update the validation around variant_infos, fallback_variant,
and default_variant: instead of allowing a fallback-only enum, return a
syn::Error when variant_infos.is_empty() (even if fallback_variant.is_some()),
and add a check after computing default_variant to error if default_variant ==
fallback_variant (i.e., the fallback variant was annotated #[string_default]);
reference the symbols variant_infos, fallback_variant, default_variant and the
Default impl generation so the macro emits a clear syn::Error for these invalid
patterns rather than producing code that indexes variant_infos[0] or generates
an invalid default constructor.

276-299: ⚠️ Potential issue | 🟠 Major

default support incomplete for non-String attribute types.

all_have_defaults now admits fields with default, optional, or StringEnum type, but default_fields only generates valid code for String and StringEnum. A non-optional field like #[attr(name = "size", u32, default = "0")] pub size: u32 will hit the unreachable!() panic. Additionally, optional numeric/enum fields with defaults generate Some(String) instead of parsing to the correct type (e.g., Some<u64> or Some<MyEnum>).

Either add parsing support for numeric defaults (converting string to u32/u64) or reject default for non-String attribute types during extraction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wacore/derive/src/lib.rs` around lines 276 - 299, The Default impl generation
currently handles only AttrType::String and AttrType::StringEnum and therefore
panics for numeric/non-string defaults; update the default_impl generation loop
(the code mapping over attr_fields used when all_have_defaults is true) to
handle all AttrType variants: for numeric types (u32/u64/i32/etc.) call .parse()
on the default string and emit the parsed literal (and wrap in Some(...) when
info.optional is true), for boolean parse via .parse::<bool>(), and for
enum/string-enum types reuse ::wacore::protocol::parse_string_enum to produce
the concrete enum value; ensure errors during parsing are surfaced as
compile-time panics with clear messages, and keep the existing branches for
optional fields (emit Some(parsed) or None) and non-optional fields (emit parsed
or Default::default() for StringEnum when no default).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@wacore/src/types/message.rs`:
- Around line 83-89: The to_string_val implementation for EditAttribute
currently maps Unknown(_) to "", which collapses Unknown and Empty and breaks
round-tripping; change EditAttribute::to_string_val so that the Unknown(String)
variant returns the stored inner string slice (the preserved wire value) instead
of "", leaving suppression/omission decisions to the caller (e.g., the code in
send.rs) so Unknown and Empty remain distinct.

---

Outside diff comments:
In `@wacore/derive/src/lib.rs`:
- Around line 725-790: The macro must reject unsupported fallback-only enums and
cases where the fallback variant is marked #[string_default]; update the
validation around variant_infos, fallback_variant, and default_variant: instead
of allowing a fallback-only enum, return a syn::Error when
variant_infos.is_empty() (even if fallback_variant.is_some()), and add a check
after computing default_variant to error if default_variant == fallback_variant
(i.e., the fallback variant was annotated #[string_default]); reference the
symbols variant_infos, fallback_variant, default_variant and the Default impl
generation so the macro emits a clear syn::Error for these invalid patterns
rather than producing code that indexes variant_infos[0] or generates an invalid
default constructor.
- Around line 276-299: The Default impl generation currently handles only
AttrType::String and AttrType::StringEnum and therefore panics for
numeric/non-string defaults; update the default_impl generation loop (the code
mapping over attr_fields used when all_have_defaults is true) to handle all
AttrType variants: for numeric types (u32/u64/i32/etc.) call .parse() on the
default string and emit the parsed literal (and wrap in Some(...) when
info.optional is true), for boolean parse via .parse::<bool>(), and for
enum/string-enum types reuse ::wacore::protocol::parse_string_enum to produce
the concrete enum value; ensure errors during parsing are surfaced as
compile-time panics with clear messages, and keep the existing branches for
optional fields (emit Some(parsed) or None) and non-optional fields (emit parsed
or Default::default() for StringEnum when no default).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2ec8d917-4430-48c1-86cf-fb851f6f1196

📥 Commits

Reviewing files that changed from the base of the PR and between 683e75f and d107538.

📒 Files selected for processing (12)
  • src/features/status.rs
  • wacore/derive/src/lib.rs
  • wacore/src/ib.rs
  • wacore/src/iq/blocklist.rs
  • wacore/src/iq/contacts.rs
  • wacore/src/iq/dirty.rs
  • wacore/src/iq/groups.rs
  • wacore/src/iq/privacy.rs
  • wacore/src/iq/usync.rs
  • wacore/src/protocol.rs
  • wacore/src/types/lid_pn.rs
  • wacore/src/types/message.rs

Comment thread wacore/src/types/message.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@wacore/src/types/message.rs`:
- Around line 57-73: The Unknown(EditAttribute::Unknown(_)) variant is currently
implicitly treated as an edit by the edit-only predicate (which only excluded
Empty and AdminRevoke); explicitly decide and implement the outbound behavior by
updating the edit-only check (e.g., the function computing edit-only send flags
/ is_edit_only) to match EditAttribute::Unknown(_) -> false (do not treat
unknown wire values as edits) and add a regression test that constructs
EditAttribute::Unknown("99".into()) and asserts it does not produce
edit-specific send flags.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6cd77c8a-4743-4e93-b5f0-53586b9864fd

📥 Commits

Reviewing files that changed from the base of the PR and between d107538 and 189093e.

📒 Files selected for processing (1)
  • wacore/src/types/message.rs

Comment on lines +57 to 73
#[derive(Debug, Clone, PartialEq, Eq, Serialize, crate::StringEnum)]
pub enum EditAttribute {
#[default]
#[string_default]
#[str = ""]
Empty,
#[str = "1"]
MessageEdit,
#[str = "2"]
PinInChat,
#[str = "3"]
AdminEdit,
#[str = "7"]
SenderRevoke,
#[str = "8"]
AdminRevoke,
#[string_fallback]
Unknown(String),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Make Unknown explicit in edit-only send logic.

Line 72 makes unknown wire values representable, but the predicate documented on Lines 171-173 now treats every Unknown(_) as an edit because it only excludes Empty and AdminRevoke. That means a future value like "99" will start emitting edit-specific send flags, even though Line 169 already notes the server rejects some mismatches. Please decide the outbound behavior for Unknown explicitly and lock it in with a regression test here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wacore/src/types/message.rs` around lines 57 - 73, The
Unknown(EditAttribute::Unknown(_)) variant is currently implicitly treated as an
edit by the edit-only predicate (which only excluded Empty and AdminRevoke);
explicitly decide and implement the outbound behavior by updating the edit-only
check (e.g., the function computing edit-only send flags / is_edit_only) to
match EditAttribute::Unknown(_) -> false (do not treat unknown wire values as
edits) and add a regression test that constructs
EditAttribute::Unknown("99".into()) and asserts it does not produce
edit-specific send flags.

@jlucaso1
jlucaso1 merged commit ade81a0 into main Mar 11, 2026
7 checks passed
@jlucaso1
jlucaso1 deleted the refactor-improve-macro-derive branch March 11, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant