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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
MessageType returns the fully-qualified protobuf name bound to the Codec.
type Constructor ¶
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.
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. |