Skip to content

v0.2.0

Choose a tag to compare

@filipsajdak filipsajdak released this 21 Sep 12:25
· 403 commits to main since this release
9410bd3

v0.2.0

Three JSON codecs to choose between, three protocol bindings, and the cross-SDK
testing that found a defect in the first binding.

Additive throughout: ce::v1 gained entities and lost none, so code written
against v0.1.0 compiles unchanged.

Added

  • Codecs. ce::codec_rapidjson and ce::codec_boost_json beside nlohmann.
    CE_CODECS takes any set, or none; CE_DEFAULT_CODEC still works and now
    subtracts from the list. README.md says which to choose, from what bench/
    measured.
  • Kafka binding (ce::kafka): binary and structured mode, ce_ prefix,
    byte-exact record header keys, unescaped UTF-8 values, to_record with an
    opt-in partitionkey_mapper. No batch mode, which the binding spec does not
    define.
  • NATS binding (ce::nats): structured mode and the JSON event format,
    which is all the protocol supports. No subject is derived.
  • ce::binding: what the three bindings share, parameterised by a
    binding_traits type, so a fourth is its traits plus its entry points.
  • ce::http::literal_values: an opt-in value policy for talking to the Go
    and Java SDKs. The default still percent-encodes, as the binding spec
    requires.
  • headers::find_exact / contains_exact / set_exact, byte-exact beside
    the case-insensitive originals.
  • ce::to_bytes / ce::to_text are public.

Fixed

  • nlohmann_codec::as_int reports out_of_range for an unsigned integer past
    INT64_MAX rather than reinterpreting it. 2^63 used to arrive as a negative
    int32 that the format layer accepted.
  • Surrogate pairs combine into one UTF-8 character.
  • Boost.JSON values are constructed with parentheses; braces selected the
    initializer_list overload on Boost 1.83 and not on 1.92.

Interoperability, measured 2026-09-21

  • The HTTP binding spec requires percent-encoded header values. sdk-go
    v2.15.2 and sdk-java implement neither encoding nor decoding; sdk-csharp
    does.
    A conformant sender is therefore silently misread by Go and Java: an
    event whose subject is a b arrives as a%20b. Name
    ce::http::literal_values when talking to them. docs/DECISIONS.md D-HTTP-1
    has the tables, cloudevents/spec#1397 the cross-SDK picture.
  • An event that round-trips through the Go SDK loses its UTC offset. Go
    rewrites 2026-09-20T12:34:56+02:00 to ...10:34:56Z. The instant survives,
    the text does not, and ce::timestamp compares by value, so the same moment
    can compare unequal.
  • Of 21 binding-level cases run through sdk-go, 14 agree. The four that differ
    are in interop/audit/README.md, with which specification says who is right.

Verified on this commit

  • Coverage 95.9% (1160 of 1209 lines), floor 90%.
  • Seven fuzz targets, 649 to 678 seconds each, no crash, leak or timeout.
  • AddressSanitizer and UndefinedBehaviorSanitizer clean over the whole suite.
  • 150 requirements lint and trace; 434 test suites resolve with no warnings.
  • Go and Java accepted every document this SDK produced.
  • Built and tested on gcc-13 (C++20 and C++23), clang-16 (C++20, libstdc++ 13),
    clang-17 (C++23, libc++), AppleClang (C++20 and C++23), MSVC (C++20), GCC 16
    with -freflection for C++26 static reflection, and g++-14 for the forced
    result<T> polyfill and -fno-exceptions builds.

Known limitations

  • libc++ 17 and 18 implement std::format without defining
    __cpp_lib_format; the SDK carves them out by version (D-CI-1).
  • Clang 16 cannot compile libstdc++ 13 or 14 in C++23 mode, so the C++23 Clang
    job uses libc++ (D-CI-1).
  • The module interface is usable, with constraints on what an importing
    translation unit may also include (D-MODULE-1).
  • Given the same non-JSON payload, the Java SDK writes data_base64 where Go
    and this SDK write a JSON string. Both are legal (D-INTEROP-1).
  • Boost.JSON requires exceptions; the build refuses it under -fno-exceptions
    at configure time.