Skip to content

Releases: phiryll/lexy

v0.5.1 - Docs, Linting, and Test Coverage

16 Sep 23:36
d068bd5

Choose a tag to compare

No changes to non-test code other than comments and one error string.

What's Changed

Full Changelog: v0.5.0...v0.5.1

v0.5.0 - Major refactor and API changes

12 Sep 06:00
5c3d531

Choose a tag to compare

What's Changed

Pretty much everything has changed except most of the encodings.

Breaking encoding change

The encoding for Negate(codec) previously always escaped and terminated its delegate Codec. It no longer does that for delegates for which RequiresTerminator returns false. This arose as a result of clarifying (and comprehending) when RequiresTerminator actually needs to return true.

It is possible to successfully read values encoded with the previous behavior, but it's not trivial. If you need to do this, please let me know and I'll work up an example.

New Codec definition

Lexy now uses byte slices, not io.Readers and Writers. The new Codec interface is (doc comments are only summarized here):

type Codec[T any] interface {
	// Append encodes value and appends the encoded bytes to buf, returning the updated buffer.
	Append(buf []byte, value T) []byte

	// Put encodes value into buf, returning buf following what was written.
	Put(buf []byte, value T) []byte

	// Get decodes a value of type T from buf, returning the value and buf following the encoded value.
	Get(buf []byte) (T, []byte)

	// RequiresTerminator returns whether encoded values require escaping and a terminator
	// if more data is written following the encoded value.
	RequiresTerminator() bool
}

Methods no longer return errors, they should panic if they cannot succeed. If you're making your own custom Codecs, please read the doc comments for RequiresTerminator, its definition has changed.

There were a few reasons for this drastic change:

  • Creating a user-defined Codec is much, much simpler.
  • Encoding and decoding is a few orders of magnitude faster.
  • The flexibility of I/O streams isn't worth the complexity it brings. The use cases for lexy will almost always be in building fairly small encodings.
  • The Codec implementations are simpler, although care has to be taken to not modify buffers outside what the API mandates. See TestIndexingBeyondSliceLength in lexy_test.go for an example that might be a little surprising.

Having implemented a streaming I/O variant was worthwhile though. It forced me to think much more carefully about error conditions and edge cases.

Removed the NillableCodec interface

There is now a NilsLast(codec) function which only works on the pointer, []byte, slice, map, and *big.Int/Float/Rat Codecs provided by lexy.

Changed helpers for building custom Codecs

  • Removed ReadPrefix, WritePrefix, and UnexpectedIfEOF.
  • Added a Prefix interface with two implementations, PrefixNilsFirst and PrefixNilsLast.

Other miscellaneous changes

  • Renamed Make...() functions to the more accurate Cast...().
  • Removed TerminateIfNeeded. Terminate now behaves the way this did.
  • Removed TerminatedBigFloat.
  • Removed Encode and Decode convenience functions.
  • Added benchmarks. They can be a bit flaky though.
  • A lot of performance optimization.
  • Much more robust testing of all Codecs.

Pull Requests

  • Major refactor - add []byte methods to Codec by @phiryll in #92
  • Refactored fuzz tests, much simpler and more comprehensive now. by @phiryll in #95
  • update docs for api changes by @phiryll in #96
  • Remove NillableCodec, add NilsLast(Codec) function. by @phiryll in #97
  • Enable revive:flag-parameter linting rule and make suggested changes. by @phiryll in #98
  • Remove Codec.Read/Write methods by @phiryll in #102
  • Implement nilsLast() for appropriate casting Codecs. by @phiryll in #104
  • Change Codec.Get and Put return values by @phiryll in #105
  • Add benchmarking by @phiryll in #106
  • Rename MakeFoo to more accurate CastFoo by @phiryll in #107
  • establish benchmark baseline by @phiryll in #108
  • Correct RequiresTerminator docs and usage by @phiryll in #109
  • Optimizations for Negate, Terminate, and big.* by @phiryll in #110
  • Minor cleanup of tests, linting, ... by @phiryll in #111

Full Changelog: v0.4.2...v0.5.0

v0.4.2 - Extensive linting and a few doc fixes

15 Aug 01:17
8f98d4e

Choose a tag to compare

What's Changed

  • Yet more minor doc comment fixes. by @phiryll in #80
  • A lot of linting by @phiryll in #81
  • Add golangci-lint config. by @phiryll in #82
  • Add golangci lint github action by @phiryll in #83
  • Fix README build status badge, yaml file name was changed. by @phiryll in #84
  • Decouple non-underlying type Codecs by @phiryll in #85
  • Remove unused receivers and enable the linting rule for that. by @phiryll in #86

Full Changelog: v0.4.1...v0.4.2

v0.4.1 - Improved documentation and examples

10 Aug 05:18
cc6201b

Choose a tag to compare

There were no functional changes to the non-test code.

What's Changed

Full Changelog: v0.4.0...v0.4.1

v0.4.0 - Big API Changes, Good Public Docs

09 Aug 06:11
6c720d4

Choose a tag to compare

What's Changed

Removed the use of all Go features released after Go 1.18, so lexy can be used in more environments. This has impacted the public API, but in ways that make it more usable and better aligned with Go's idiomatic style. All the examples were updated to reflect this as well.

  • Go 1.22 added reflection for generic type parameters
    • Removed support for arrays (ArrayOf, PointerToArrayOf). Added an example showing how to create a Codec to cover this use case.
    • Separated Uint() and Int() into 5 distinct API methods each, one for each size and one each for uint/int. There was a workaround, but it required using the unsafe package. This is more idiomatic anyway, generics were being overused here.
  • Go 1.21 added much better type inference for generics.
    • Losing the improved type inference required a very large refactoring, but this did not affect the public API. I strongly suggest upgrading to at least Go 1.21 if you're using generics, the better type inference helps make code a lot cleaner.
  • Added matrix testing of Go versions 1.18, 1.19, 1.20, 1.21, and 1.22 to the GitHub build/test workflow.

Extensively changed the public API (but not the encodings!).

  • Most of the Codec-returning functions now have two forms. The gist is that the common use cases have shorter function names and don't require specifying a type parameter to invoke. See the package docs for details. For example:
    • Int32() returns a Codec[int32]
    • MakeInt32[MyInt]() returns a Codec[MyInt], where MyInt has an underlying type of int32
    • Empty[T]() also requires a type parameter to invoke, the only exception to the Make... naming convention.
  • All of the Codec-returning functions which don't require a type parameter to invoke, and which also don't delegate to a user-provided Codec (i.e., pointers, slices, maps, negate, terminate), now each return a single, essentially constant, instance. This doesn't change the API, but the performance benefit may be noticeable.
  • Added Codec-returning functions for terminated string, *big.Float, and []byte Codecs. These also each return a single, shared instance.
  • Added the NillableCodec[T] interface, an extension of Codec[T] with the additional method NilsLast() NillableCodec[T]. The idiom for creating a Codec which orders nil last instead of first now looks like codec := lexy.Bytes().NilsLast().
    • Codec-returning functions handling []byte, *big.Float, *big.Int, *big.Rat, and general pointer, slice, and map types now return a NillableCodec
    • Removed the func SomeTypeNilsLast() Codec[SomeType] functions for these same types.

Significantly improved the README, the lexy package docs, and the doc comments for all public API elements.

Pull Requests

Full Changelog: v0.3.0...v0.4.0

v0.4.0-rc1

09 Aug 04:29
0092561

Choose a tag to compare

v0.4.0-rc1 Pre-release
Pre-release

What's Changed

Removed the use of all Go features released after Go 1.18, so lexy can be used in more environments. This has impacted the public API, but in ways that make it more usable and better aligned with Go's idiomatic style. All the examples were updated to reflect this as well.

  • Go 1.22 added reflection for generic type parameters
    • Removed support for arrays (ArrayOf, PointerToArrayOf). Added an example showing how to create a Codec to cover this use case.
    • Separated Uint() and Int() into 5 distinct API methods each, one for each size and one each for uint/int. There was a workaround, but it required using the unsafe package. This is more idiomatic anyway, generics were being overused here.
  • Go 1.21 added much better type inference for generics.
    • Losing the improved type inference required a very large refactoring, but this did not affect the public API. I strongly suggest upgrading to at least Go 1.21 if you're using generics, the better type inference helps make code a lot cleaner.
  • Added matrix testing of Go versions 1.18, 1.19, 1.20, 1.21, and 1.22 to the GitHub build/test workflow.

Extensively changed the public API (but not the encodings!).

  • Most of the Codec-returning functions now have two forms. The gist is that the common use cases have shorter function names and don't require specifying a type parameter to invoke. See the package docs for details. For example:
    • Int32() returns a Codec[int32]
    • MakeInt32[MyInt]() returns a Codec[MyInt], where MyInt has an underlying type of int32
    • Empty[T]() also requires a type parameter to invoke, the only exception to the Make... naming convention.
  • All of the Codec-returning functions which don't require a type parameter to invoke, and which also don't delegate to a user-provided Codec (pointers, slices, maps, negate, terminate), now each return a single, essentially constant, instance. This doesn't change the API, but the performance benefit may be noticeable.
  • Added Codec-returning functions for terminated string, *big.Float, and []byte Codecs. These are also each a single, shared instance.
  • Added the NillableCodec[T] interface, an extension of Codec[T] with the additional method NilsLast() NillableCodec[T]. The idiom for creating a Codec which orders nil last instead of first now looks like codec := lexy.Bytes().NilsLast().
    • Codec-returning functions handling []byte, *big.Float, *big.Int, *big.Rat, and general pointer, slice, and map types now return a NillableCodec
    • Removed the func SomeTypeNilsLast() Codec[SomeType] functions for these same types.

Significantly improved the README, the lexy package docs, and the doc comments for all public API elements.

Pull Requests

Full Changelog: v0.3.0...v0.4.0-rc1

v0.3.0

06 Aug 02:16
11e4cde

Choose a tag to compare

What's Changed

Full Changelog: v0.2.0...v0.3.0

Release flow fixed... hopefully

03 Aug 01:23
428a3cc

Choose a tag to compare

What's Changed

  • Fix release workflow attempt 1 (#62)

Full Changelog: v0.2.0-alpha.2...v0.2.0

Fix release flow

02 Aug 21:51
428a3cc

Choose a tag to compare

Fix release flow Pre-release
Pre-release

Version ...-alpha.2 pushed to pkg.go.dev, and we don't want to do that, because it was pre-release.
Chang the event type from "published" to "released", see if that works.

What's Changed

  • Fix release workflow attempt 1 (#62)

Full Changelog: v0.2.0-alpha.2...v0.2.0-alpha.3

Testing that release action does not fire on pre-release

02 Aug 21:38
1d99294

Choose a tag to compare

What's Changed

  • Add CODEOWNERS file (#52)
  • Add badges to README (#53, #56, #57)
  • Add publish workflow (#60)
  • Fix misspellings in docs (#54)
  • Run github test actions against multiple go versions (#55)

Full Changelog: v0.2.0-alpha.1...v0.2.0-alpha.2