contracts API

contracts

package

API reference for the contracts package.

S
struct

Implements

Implements is a zero-cost marker used to declare that a struct implements an interface T.

Usage:

type MyService struct {
contracts.Implements[IService]
}

This enables:
1. IDE navigation: Clicking IService takes you to the interface definition.
2. IDE discovery: “Find Usages” on IService will show MyService.
3. Runtime validation: contracts.Verify(&MyService{}) checks if the implementation is valid.

pkg/contracts/implements.go:20-20
type Implements struct
I
interface

validator

validator is an internal interface used by Verify to identify contract markers.

pkg/contracts/implements.go:23-25
type validator interface

Methods

Parameters

any

Returns

error
func validateContract(...)
F
function

Verify

Verify checks if the given instance satisfies all its declared contracts.
It scans for fields of type contracts.Implements[T] and validates them.

Parameters

v
any

Returns

error
pkg/contracts/implements.go:40-75
func Verify(v any) error

{
	val := reflect.ValueOf(v)
	if val.Kind() == reflect.Invalid {
		return nil
	}

	typ := val.Type()
	// Contract markers are usually placed in the struct, but we validate against the pointer
	// if the instance is a pointer, because method sets often depend on the pointer receiver.
	baseTyp := typ
	if baseTyp.Kind() == reflect.Ptr {
		baseTyp = baseTyp.Elem()
	}

	if baseTyp.Kind() != reflect.Struct {
		return nil
	}

	for i := 0; i < baseTyp.NumField(); i++ {
		field := baseTyp.Field(i)
		
		// We check if the field type implements our internal validator interface.
		// Since Implements[T] has a value receiver for validateContract, 
		// both the type and its pointer will implement it.
		if field.Type.Implements(reflect.TypeOf((*validator)(nil)).Elem()) {
			// Instantiate the field type to call validateContract.
			// Since it's a zero-sized struct, this is cheap.
			vld := reflect.New(field.Type).Elem().Interface().(validator)
			if err := vld.validateContract(v); err != nil {
				return err
			}
		}
	}

	return nil
}
F
function

MustVerify

MustVerify is like Verify but panics if a contract is violated.

Parameters

v
any
pkg/contracts/implements.go:78-82
func MustVerify(v any)

{
	if err := Verify(v); err != nil {
		panic(err)
	}
}
I
interface

Greeter

pkg/contracts/implements_test.go:7-9
type Greeter interface

Methods

Greet
Method

Returns

string
func Greet(...)
S
struct
Implements: Greeter

MyGreeter

pkg/contracts/implements_test.go:11-13
type MyGreeter struct

Methods

Greet
Method

Returns

string
func (*MyGreeter) Greet() string
{
	return "Hello"
}
S
struct

BadGreeter

pkg/contracts/implements_test.go:19-21
type BadGreeter struct
F
function

TestVerify

Parameters

pkg/contracts/implements_test.go:23-48
func TestVerify(t *testing.T)

{
	t.Run("Valid implementation", func(t *testing.T) {
		g := &MyGreeter{}
		if err := Verify(g); err != nil {
			t.Fatalf("expected no error, got %v", err)
		}
	})

	t.Run("Invalid implementation", func(t *testing.T) {
		g := &BadGreeter{}
		err := Verify(g)
		if err == nil {
			t.Fatal("expected error, got nil")
		}
		expected := "contract violation: *contracts.BadGreeter does not implement contracts.Greeter"
		if err.Error() != expected {
			t.Fatalf("expected %q, got %q", expected, err.Error())
		}
	})

	t.Run("Non-struct type", func(t *testing.T) {
		if err := Verify(42); err != nil {
			t.Fatalf("expected no error for non-struct, got %v", err)
		}
	})
}