liquidproto

package
v0.2.8 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package liquidproto provides the small runtime used by Liquid Proto generated code and deterministic, validating protobuf serialization.

Refinement predicates are compiled into generated Go. This package does not interpret predicates at run time. Generated Validate<Message> functions enforce scalar and enum refinements at serialization and service boundaries.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNilConstructor indicates that a Codec was configured without a
	// message constructor.
	ErrNilConstructor = errors.New("liquidproto: nil message constructor")
	// ErrNilValidator indicates that a Codec was configured without a
	// contract validator.
	ErrNilValidator = errors.New("liquidproto: nil message validator")
	// ErrNilMessage indicates that a caller supplied, or a constructor
	// returned, a typed nil protobuf message.
	ErrNilMessage = errors.New("liquidproto: nil protobuf message")
	// ErrWrongMessageType indicates that a caller supplied a protobuf type that
	// differs from the constructor bound to the Codec.
	ErrWrongMessageType = errors.New("liquidproto: wrong protobuf message type")
)

Functions

func FormatValue

func FormatValue(v any) string

FormatValue renders a rejected value without placing string or byte content in diagnostics. Error.Value retains the raw value for trusted callers using errors.As, while Error() remains safe to put in production logs.

Types

type Codec

type Codec[T proto.Message] struct {
	// contains filtered or unexported fields
}

Codec deterministically marshals and validates one protobuf message type.

A Codec validates immediately before Marshal and immediately after Unmarshal. The constructor must return a fresh, non-nil message on every call. Codec values are safe for concurrent use when the supplied functions are safe for concurrent use.

func NewCodec

func NewCodec[T proto.Message](construct Constructor[T], validate Validator[T]) (*Codec[T], error)

NewCodec constructs a validating deterministic protobuf codec.

Example
package main

import (
	"errors"
	"fmt"

	"github.com/candacelabs/csf/pkg/liquidproto"
	"google.golang.org/protobuf/types/known/wrapperspb"
)

func main() {
	codec, err := liquidproto.NewCodec(
		func() *wrapperspb.StringValue { return new(wrapperspb.StringValue) },
		func(message *wrapperspb.StringValue) error {
			if message.GetValue() == "" {
				return errors.New("value is empty")
			}
			return nil
		},
	)
	if err != nil {
		panic(err)
	}

	wire, err := codec.Marshal(wrapperspb.String("hello"))
	if err != nil {
		panic(err)
	}
	decoded, err := codec.Unmarshal(wire)
	if err != nil {
		panic(err)
	}

	fmt.Println(codec.MessageType())
	fmt.Println(decoded.GetValue())
}
Output:
google.protobuf.StringValue
hello

func (*Codec[T]) Marshal

func (c *Codec[T]) Marshal(message T) ([]byte, error)

Marshal validates message and returns deterministic protobuf wire bytes.

Deterministic protobuf encoding is stable for repeated marshals by the same binary. Protobuf does not define it as a canonical encoding across languages or schema changes, so callers must not use these bytes as a permanent hash.

func (*Codec[T]) MessageType

func (c *Codec[T]) MessageType() string

MessageType returns the fully-qualified protobuf name bound to the Codec.

func (*Codec[T]) New

func (c *Codec[T]) New() (T, error)

New returns a fresh non-nil message from the configured constructor. It is useful for descriptor inspection and integrations that need a typed decode target. The returned empty message has not passed validation.

func (*Codec[T]) Unmarshal

func (c *Codec[T]) Unmarshal(wire []byte) (T, error)

Unmarshal decodes wire into a fresh message and validates the result. Unknown protobuf fields are retained for forward-compatible re-encoding.

type Constructor

type Constructor[T proto.Message] func() T

Constructor returns a fresh protobuf message for one Unmarshal call.

type Error

type Error struct {
	// Message is the fully-qualified protobuf message name.
	Message string
	// Field is the protobuf field name.
	Field string
	// Predicate is the source expression from the field option.
	Predicate string
	// Value is the rejected value in its base Go type.
	Value any
}

Error reports a value that failed a protobuf field refinement.

Generated message validators return *Error so callers can inspect the exact contract violation with errors.As.

func (*Error) Error

func (e *Error) Error() string

type Validator

type Validator[T proto.Message] func(message T) error

Validator checks the complete application contract for a message.

Directories

Path Synopsis
cmd
protoc-gen-liquidproto command
protoc-gen-liquidproto compiles Liquid Proto field refinements into native Go validation boundaries.
protoc-gen-liquidproto compiles Liquid Proto field refinements into native Go validation boundaries.
protoc-gen-liquidproto/internal/expr
Package expr compiles the small Liquid Proto predicate grammar to Go.
Package expr compiles the small Liquid Proto predicate grammar to Go.
protoc-gen-liquidproto/internal/gen
Package gen turns Liquid Proto field refinements into Go validators.
Package gen turns Liquid Proto field refinements into Go validators.

Jump to

Keyboard shortcuts

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