Skip to content

refactor(tuic-core): replace manual byte parsing with nom streaming parsers#16

Merged
Itsusinn merged 4 commits into
mainfrom
feat/tuic-core-nom-parsers
Jun 7, 2026
Merged

refactor(tuic-core): replace manual byte parsing with nom streaming parsers#16
Itsusinn merged 4 commits into
mainfrom
feat/tuic-core-nom-parsers

Conversation

@Itsusinn

@Itsusinn Itsusinn commented Jun 7, 2026

Copy link
Copy Markdown
Member

Summary

Replace the two sets of hand-written byte-parsing code (free helpers + tokio-util Decoder impls) with a single set of nom 8 streaming parsers.

Problem

tuic-core maintained two parallel parsing implementations — free helper functions (decode_header, decode_command, decode_address) and tokio-util Decoder/Encoder codecs — with identical parsing logic but different error contracts. The comment explicitly warned "Any change to the on-wire format MUST be mirrored across both implementations."

Solution

Define a single set of nom streaming parsers:

Parser Input Output
parse_header &[u8] (&[u8], Header)
parse_command_body &[u8] (&[u8], Command)
parse_address &[u8] (&[u8], Address)

Both paths call the same parsers, differing only in how nom::Err::Incomplete is mapped:

  • Codec path: IncompleteOk(None) (tokio-util contract)
  • Free helpers: IncompleteErr(eyre!("Incomplete data in ..."))

Encoder implementations are unchanged (nom is parsing-only).

Changes

  • Cargo.toml — add nom = "8"
  • src/proto/mod.rs — core parsers + nom_parse() wrapper + updated free helpers; ~110 lines of manual parsing deleted
  • src/proto/header.rsHeaderCodec::decode calls parse_header
  • src/proto/cmd.rsCmdCodec::decode calls parse_command_body
  • src/proto/addr.rsAddressCodec::decode calls parse_address

Verification

  • All 18 tuic-core unit tests pass
  • All downstream crates (wind-tuic, wind-tuiche, tuic-tests) compile without changes
  • tuic-tests protocol and integration tests pass
  • Clippy clean (zero warnings)
6 files changed, 183 insertions(+), 277 deletions(-)

Itsusinn added 4 commits June 7, 2026 12:34
…arsers

Replace the two sets of hand-written byte-parsing code (free helpers +
tokio-util Decoder impls) with a single set of nom 8 streaming parsers.
Both paths now use the same nom combinators; the only difference is how
`nom::Err::Incomplete` is mapped — to `Ok(None)` in the codec path and
to an `eyre::Report` error in the free helpers.

- Add nom = "8" dependency
- Define parse_header / parse_command_body / parse_address in mod.rs
- Rewrite free helpers (decode_*) as thin wrappers around nom_parse()
- Rewrite codec Decoder impls to call the same nom parsers
- Encoder impls remain unchanged (nom is parsing-only)
- All 18 tuic-core tests pass, all downstream crates compile clean
quinn's QuicServerConfig requires max_early_data_size to be either 0 or
u32::MAX. The previous value of 16 KiB violated this constraint, causing
a panic at quinn-proto/src/crypto/rustls.rs:526.
@Itsusinn Itsusinn merged commit 0f6a2a3 into main Jun 7, 2026
17 checks passed
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