stream

package
v2.702.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package stream provides streaming (multi-value) encode/decode interfaces used by go-service.

Unlike github.com/alexfalkowski/go-service/v2/encoding, which models exactly one value per Encode/Decode call against a writer/reader supplied per call, this package models a sequence of values written to, or read from, one writer or reader bound at construction time. Encoder and Decoder are separate interfaces, rather than one combined interface, because the underlying per-kind codecs construct distinct encoder and decoder types that are each bound to a single direction.

Per-kind implementations live in sibling packages (github.com/alexfalkowski/go-service/v2/encoding/stream/json, .../msgpack, .../gob, .../yaml), each exporting NewEncoder(io.Writer) Encoder and NewDecoder(io.Reader) Decoder. They wrap the same underlying libraries as the sibling encoding/<kind> packages, carrying over the same policy with two exceptions needed for multi-value streams: no output indentation (which would break newline-delimited framing) and no trailing-data rejection (a stream is expected to contain many values). Strict/unknown- field decoding is preserved.

Start with Encoder and Decoder.

Index

Constants

This section is empty.

Variables

Module provides the default streaming encoder/decoder registry as a *Map.

Functions

This section is empty.

Types

type Decoder

type Decoder interface {
	// Decode reads the next value from the underlying reader into v. Decode returns io.EOF once the
	// stream is exhausted.
	Decode(v any) error

	// Close finalizes the decoder. Close never closes the underlying reader. Close is called exactly
	// once; a second call is not guaranteed to be safe.
	Close() error
}

Decoder decodes a sequence of values from a reader bound at construction.

Decoder differs from github.com/alexfalkowski/go-service/v2/encoding.Encoder's Decode in two ways: it is bound to one reader for its entire lifetime (constructed with the reader rather than given one per call), and it is expected to serve many Decode calls rather than exactly one.

Decode contract

Decode reads the next encoded value from the underlying reader and populates v. In most cases v should be a pointer to the destination value (for example *MyStruct). Decode returns io.EOF once the underlying stream is exhausted, matching the terminal behavior of the wrapped codec's own decoder.

Close contract

Close finalizes any codec-level state. Close must never close the underlying reader — the reader is owned by the caller, not the Decoder. Close is called exactly once; implementations are not required to tolerate a second call.

type DecoderFunc

type DecoderFunc func(r io.Reader) Decoder

DecoderFunc constructs a Decoder bound to r. Registered in a Map by kind via Map.RegisterDecoder, and returned by Map.GetDecoder.

type Encoder

type Encoder interface {
	// Encode writes a serialized representation of v to the underlying writer.
	Encode(v any) error

	// Close finalizes the encoder. Close never closes the underlying writer. Close is called exactly
	// once; a second call is not guaranteed to be safe.
	Close() error
}

Encoder encodes a sequence of values to a writer bound at construction.

Encoder differs from github.com/alexfalkowski/go-service/v2/encoding.Encoder in two ways: it is bound to one writer for its entire lifetime (constructed with the writer rather than given one per call), and it is expected to serve many Encode calls rather than exactly one.

Encode contract

Encode serializes v and writes it to the underlying writer. Implementations may require that v satisfies additional interfaces or is of a particular shape, matching the wrapped codec's own requirements. Callers may call Encode repeatedly to write multiple values to the same stream.

Close contract

Close finalizes any codec-level state (for example a stream terminator or trailer). Close must never close the underlying writer — the writer is owned by the caller, not the Encoder. Close is called exactly once, at the true end of the stream: implementations are not required to tolerate a second call (for example encoding/stream/yaml's Encoder is a direct alias of a non-idempotent upstream Close), so callers must not both defer Close and call it explicitly on the success path.

type EncoderFunc

type EncoderFunc func(w io.Writer) Encoder

EncoderFunc constructs an Encoder bound to w. Registered in a Map by kind via Map.RegisterEncoder, and returned by Map.GetEncoder.

type Map

type Map struct {
	// contains filtered or unexported fields
}

Map provides lookup and registration of streaming encoder/decoder constructors by kind.

Unlike github.com/alexfalkowski/go-service/v2/encoding.Map, which registers ready-to-use encoder instances, Map registers constructor functions. Each streaming Encode/Decode call needs a fresh Encoder or Decoder bound to its own writer or reader, so the registry stores how to build one rather than a shared instance.

Map is not concurrency-safe. If you mutate it via RegisterEncoder or RegisterDecoder, do so during initialization.

func NewMap

func NewMap() *Map

NewMap constructs a Map with the default streaming encoder/decoder constructors.

The returned registry includes these kinds: "json", "msgpack", "gob", "yaml".

Each per-kind package (encoding/stream/json, .../msgpack, .../gob, .../yaml) exports constructors returning its own concrete json.Encoder/json.Decoder-shaped type rather than the Encoder/Decoder interfaces, so those packages do not import this one back — avoiding a compile-time import cycle, since this package imports them here to build the default registry. The adapter closures below convert each concrete constructor to the registry's constructor-function shape; the concrete types satisfy Encoder/Decoder structurally, so the conversion is just an ordinary interface assignment on return.

Callers can add additional kinds or override existing kinds via Map.RegisterEncoder and Map.RegisterDecoder.

func (*Map) GetDecoder

func (m *Map) GetDecoder(kind string) DecoderFunc

GetDecoder returns the decoder constructor registered for kind.

If no decoder constructor is registered for kind, or if kind was registered with a nil constructor, GetDecoder returns nil. Callers typically treat nil as "unknown or unavailable kind" and fail explicitly rather than falling back to a default decoder.

GetDecoder is nil-safe: it returns nil for a nil m, so resolving against an unconfigured registry fails the same way resolving an unregistered kind does, rather than panicking.

func (*Map) GetEncoder

func (m *Map) GetEncoder(kind string) EncoderFunc

GetEncoder returns the encoder constructor registered for kind.

If no encoder constructor is registered for kind, or if kind was registered with a nil constructor, GetEncoder returns nil. Callers typically treat nil as "unknown or unavailable kind" and fail explicitly rather than falling back to a default encoder.

GetEncoder is nil-safe: it returns nil for a nil m, so resolving against an unconfigured registry fails the same way resolving an unregistered kind does, rather than panicking.

func (*Map) Keys

func (m *Map) Keys() []string

Keys returns the union of registered encoder and decoder kinds.

Keys includes kinds registered with nil constructors. The returned slice is not guaranteed to be sorted.

func (*Map) RegisterDecoder

func (m *Map) RegisterDecoder(kind string, fn DecoderFunc)

RegisterDecoder associates kind with fn, overwriting any existing decoder constructor.

If kind already exists, the previous decoder constructor is replaced.

func (*Map) RegisterEncoder

func (m *Map) RegisterEncoder(kind string, fn EncoderFunc)

RegisterEncoder associates kind with fn, overwriting any existing encoder constructor.

If kind already exists, the previous encoder constructor is replaced.

Directories

Path Synopsis
Package gob provides a streaming gob github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package gob provides a streaming gob github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package json provides a streaming JSON github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package json provides a streaming JSON github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package msgpack provides a streaming MessagePack github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package msgpack provides a streaming MessagePack github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package yaml provides a streaming YAML github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.
Package yaml provides a streaming YAML github.com/alexfalkowski/go-service/v2/encoding/stream.Encoder/ github.com/alexfalkowski/go-service/v2/encoding/stream.Decoder pair used by go-service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL