Skip to content

v0.1012.0

Pre-release
Pre-release
Compare
Choose a tag to compare
@mumbleskates mumbleskates released this 21 Jan 10:13
· 3 commits to bilrost since this release

v0.1012.0

Breaking changes

  • This release includes a major overhaul of encoding and decoding traits for
    the library.

    Capability Old trait New trait
    encoding Message Message
    relaxed decoding (owned) Message OwnedMessage
    distinguished decoding (owned) DistinguishedMessage DistinguishedOwnedMessage
    relaxed decoding (borrowed) (new!) BorrowedMessage<'a>
    distinguished decoding (borrowed) (new!) DistinguishedBorrowedMessage<'a>

    For very simple usage of the bilrost library, this will now probably mean
    importing both Message and OwnedMessage traits to have the desired
    functionality in scope.

  • The DistinguishedMessage and DistinguishedOneof traits & derives are gone
    as well; rather than deriving multiple traits, simply add a
    #[bilrost(distinguished)] attribute to the type being derived from:

    Old derives New derives
    Message, DistinguishedMessage Message with #[bilrost(distinguished)] on the struct
    Oneof, DistinguishedOneof Oneof with #[bilrost(distinguished)] on the enum
    all of the above Message & Oneof with #[bilrost(distinguished)] on the enum
    just using Message, Oneof, & Enumeration (no change)

New features

  • It is now possible to do borrowed zero-copy decoding, which is enabled by
    default and available in the derive macros. This decodes from a &[u8] slice
    with lifetime into messages that may reference its data.
    • This adds support for the types &str, &[u8], &[u8; N], and
      &bstr::BStr; these types can appear in message fields, oneof fields, and
      nested in other containers just like any other type. This also adds
      guaranteed behavior for Cow for these borrowed types also decodes as
      Cow::Borrowed(&..) when decoding from borrowed data.
    • With this addition, there are now two different ways to have zero-copy
      decoding that each work slightly differently:
      1. Decode directly from bytes::Bytes and into fields of type
        bytes::Bytes or bytestring::Bytestring. This yields owned, refcounted
        handles to the original data.
      2. Decode borrowed from &[u8] and into fields of type &str, &[u8],
        &[u8; N], or &bstr::BStr. This yields data borrowed for a lifetime at
        very low cost, protected by the borrow checker rather than a refcount.
  • Derive macros are now simpler to use, so now deriving all encoding and
    decoding impls for messages and oneofs is done only with Message and
    Oneof, and distinguished implementations are switched on and off by
    attribute.
  • Opened the gates for crate documentation in the encoding module as the crate
    is getting closer to what could become a stable release.
  • Added From<Vec<u8>> and From<Box<[u8]>> impls for ReverseBuffer.
  • Added new forms of ranges in the reserved_tags attribute: 5.. and ..=5.
  • EXPERIMENTAL: Made public a couple macros and the proxying traits &
    encoding type; see encoding::{Proxied, Proxiable} for details.
    • These can be used even to encode third-party types foreign to both your own
      crate and to bilrost (via type-tagged impls) and completely break the
      guarantees of the bilrost library. I do my best, but correctness is in
      your hands!

Fixes

  • Internals: It should no longer be possible for restricted and canonical
    message decoding modes to return data or canonicity that is less than the
    restriction level that was specified, if a decoding implementation returns a
    lower canonicity but forgets to check against the restriction in the context.
    The worst that should happen is that the error is raised late, at the end of
    decoding, when it is too late to add information about the location of the
    error. There are also debug-only assertions that test that this should never
    happen, and explanatory documentation about exactly when a Canonicity should
    be checked against the restricted context on RestrictedDecodeContext::check.
    • It's unlikely this should change any behavior as formerly the canonicity was
      checked very aggressively in all existing implementations, far more often
      than it had to be.

Cleanups

  • Changed internal and external phrasing from "expedient" encoding to "relaxed".
  • More reorganization and file cleanups, splitting up some large files into more
    modules etc.
  • Cleaned up some docs in the encoding module.
  • Improved type coverage in the fuzz testing modules and gave the message
    definitions fixed field tags so existing fuzzing corpora will be maximally
    useful.
  • Internals: Ironed out a lingering annoyance with the field decoding APIs; the
    Decoder traits no longer accept a duplicated boolean argument that
    mandates returning an error when it is true. Instead, message implementations
    that have defined fields are responsible for creating the
    UnexpectedlyRepeated decoding error themselves.