# parse-net v0.5.0 - Feature complete
**Date:** 2026-10-22
**Compare:** [`v0.4.0...v0.5.0`](https://github.com/jamesgober/parse-net/compare/v0.4.0...v0.5.0)
**Every planned field, for HTTP and for mail.** v0.5.0 added `Link`, the canonical Structured Field writer, RFC 5322 dates, the email lexical layer that smtp-net needs (folding, encoded words, MIME parameters with RFC 2231 continuations, addresses, message identifiers), `Forwarded` writing for proxies, and owned forms behind `alloc`. Every public item now has its own runnable example. It is still `no_std` without an allocator, with zero dependencies and no `unsafe`. Only the base64 decode helpers wait, for encode-lib (D-062).
## Highlights
- The Structured Field writer passed the httpwg serialisation suite in full, and every one of the 728 accepted parsing cases, serialized again from the parsed view, matched the suite's canonical form.
- The mail layer works without an allocator: MIME parameters split over RFC 2231 sections are reassembled through a 32-slot stack array and decoded into a caller buffer.
- Address parsing is strict enough for login validation: no comments, no obsolete forms, RFC 5321 lengths, and non-ASCII only as valid UTF-8.
- Every writer's output parses back to what was written; property tests and fuzz targets check this for each new writer.
- `docs/ARCHITECTURE.md` describes the modules, the byte-class table, the views and their sizes, and the algorithms.
## Added
- **Link.** `parse_link` with commas inside `<...>` kept, the first `rel` winning (RFC 8288 section 3.3), every `hreflang`, and `title*` decoded at parse time; `write_link`.
- **Structured Field writer.** `sfv::Writer` for Items, Lists, and Dictionaries: decimals with the shortest fraction, strings with only `\"` and `\\` escaped, byte sequences padded with zero pad bits, Display Strings with lowercase `%xx` for exactly the bytes that need it, a Boolean-true dictionary member as its key alone, and `InvalidSequence` for calls out of order. `param_key` writes a parameter whose value is not already a parsed view (D-059).
- **MailDate.** RFC 5322 `date-time`: weekday checked, comments and folding between tokens, `-0000` reported as an unknown zone, a leap second read as 59 and flagged; the obsolete two- and three-digit years and named zones on request.
- **Email lexical layer.** `check_header_value` (no CR, LF, or NUL; 998 bytes), `unfold`, `fold` (78 columns where the words allow, never a line of only whitespace), `encode_words` and `decode_words` (RFC 2047 Q, words of at most 75 bytes split between characters, adjacent-word whitespace dropped), `parse_mime_params` with RFC 2231 continuations and extended values, `write_mime_param` (token, quoted string, or `name*` sections on folded lines), `parse_addr_spec`, `parse_mailbox`, `parse_msg_id`, `write_msg_id`, `is_field_name`.
- **Forwarded writing.** `forwarded::write_element` quotes IPv6 and any node with a port.
- **Owned forms** (`alloc`). `OwnedMediaType`, `OwnedEntityTag`, `OwnedHostPort`, and `sfv::owned`: one buffer per value, and `as_view` gives back the same view.
- **`Charset::UsAscii`** for RFC 8187 and RFC 2231 values (D-058).
## Changed
- `docs/API.md`: the `MailDate` example claimed "Tue, 21 Oct 2026", which is a Wednesday; the example now passes as a doctest.
- The base64 decode helpers (ATH-3 `basic_decode_into`, MAIL-5 `encode_words_b`, `ByteSeq::decode_into`, `sfv::Writer::bytes`, and decoding `B` encoded words) moved to 0.6 because encode-lib is not published; D-002 recorded this possibility at 0.1 (D-062).
## Testing
- httpwg structured-field-tests: the 1598 parsing cases, the 728 accepted ones also serialized and compared with their canonical form, and the 547 serialisation cases.
- Property tests for every 0.5 parser (no panic on arbitrary bytes) and writer (Link, MailDate, encoded words, MIME parameters, folding, message identifiers, `Forwarded` elements, the Structured Field writer).
- Counting-allocator tests over every 0.5 parse and every write into a `SliceSink`.
- Size, `Send`, `Sync`, `Unpin`, and `Copy` checks for every 0.4 and 0.5 view.
- An example on every public item: 560 items, each with a doctest that runs.
- Seven new fuzz targets: `link`, `mail_date`, `mail_words`, `mime_params`, `addr_spec`, `fold_unfold`, `sfv_roundtrip`, each checking no panic, no allocation, and that the writer's output parses back. All 34 targets ran ten minutes clean against this release in WSL Ubuntu, 1.0 million to 58 million inputs each; the 0.4 targets had run an hour each before.
## Compatibility
- MSRV 1.85, edition 2024; `no_std` without `alloc` is the base build, built for `thumbv7em-none-eabi`.
- Zero runtime dependencies in every feature combination.
- Pre-1.0: code written against 0.4.0 compiles unchanged; `Charset` gained a variant, which its `#[non_exhaustive]` attribute allows.
## Verification
- Local gate on Windows and WSL Ubuntu, Rust 1.99 and 1.85: format, clippy with default, all, and no default features under `-D warnings`, tests in the same three modes, documentation with default and all features under `-D warnings`, the bare-metal build, and `cargo package` in a fresh target directory.
- Banned-content and link checks over every shipped file.
## What's next
`0.6.0`: benchmarks for every operation against the named competitors, SWAR fast paths where they measure faster, and `docs/PERFORMANCE.md`; base64 decoding through encode-lib if it is published.
**Full Changelog:** https://github.com/jamesgober/parse-net/compare/v0.4.0...v0.5.0