Types Reference
Complete documentation for slush's public types.
Core Types
Key
type Key struct {
// contains filtered or unexported fields
}
Capability token that authorizes service registration and enumeration. Returned by Start().
Obtaining a Key:
- Call
Start()at application startup Start()can only be called once
Operations requiring a Key:
Register[T](key, impl)— Register a serviceFreeze(key)— Lock the registryServices(key)— Enumerate services
Security:
- The inner pointer is unexported, preventing forgery via struct literal
- Only code with access to the key can modify the registry
- Keys are invalidated by
Reset()(testing only)
Example:
func main() {
key := slush.Start()
// Pass key to initialization code
initDatabase(key)
initServices(key)
// Optionally lock the registry
slush.Freeze(key)
// Key not needed for Use
db, _ := slush.Use[Database](ctx)
}
func initDatabase(key slush.Key) {
slush.Register[Database](key, newPostgresDB())
}
Guard
type Guard func(ctx context.Context) error
A function that validates context before service access.
Contract:
- Return
nilto allow access - Return an error to deny access
Behavior when returned error is non-nil:
Use[T]returnsErrAccessDeniedwrapping your error- Guard chain stops (subsequent guards don't run)
SignalDeniedevent emitted with error message
Example:
// Simple guard
func requireAuth(ctx context.Context) error {
if auth.UserFromContext(ctx) == nil {
return errors.New("unauthenticated")
}
return nil
}
// Parameterized guard
func requirePermission(perm string) slush.Guard {
return func(ctx context.Context) error {
if !hasPermission(ctx, perm) {
return fmt.Errorf("missing permission: %s", perm)
}
return nil
}
}
See also: Guards Guide, Handle.Guard
Handle
type Handle[T any] struct {
// contains filtered or unexported fields
}
Configuration handle for a registered service. Returned by Register[T].
Methods:
| Method | Description |
|---|---|
Guard(g Guard) *Handle[T] | Add access control check (chainable) |
Example:
handle := slush.Register[Database](key, db)
handle.Guard(requireAuth)
handle.Guard(requireRole("admin"))
// Or chained
slush.Register[Database](key, db).
Guard(requireAuth).
Guard(requireRole("admin"))
Internals:
Handle wraps a generic *handle[T] that stores:
- The service implementation (
impl T) - Guard slice (
[]Guard) - Pre-computed FQDNs for interface and implementation
See also: Register, Architecture
ServiceInfo
type ServiceInfo struct {
Interface string // Interface FQDN (the lookup key)
Impl string // Implementation FQDN
Metadata sentinel.Metadata // Sentinel metadata from cache
GuardCount int // Number of guards configured
}
Describes a registered service. Returned by Services().
Fields:
| Field | Type | Description |
|---|---|---|
Interface | string | Fully qualified name of the interface type (e.g., "github.com/app.Database") |
Impl | string | Fully qualified name of the implementation type (e.g., "github.com/app.postgresDB") |
Metadata | sentinel.Metadata | Type metadata from sentinel's cache (may be empty if not scanned) |
GuardCount | int | Number of guards attached to this service |
Example:
svcs, err := slush.Services(key)
if err != nil {
log.Fatal(err)
}
for _, svc := range svcs {
fmt.Printf("Service: %s\n", svc.Interface)
fmt.Printf(" Impl: %s\n", svc.Impl)
fmt.Printf(" Guards: %d\n", svc.GuardCount)
if len(svc.Metadata.Fields) > 0 {
fmt.Printf(" Fields:\n")
for _, f := range svc.Metadata.Fields {
fmt.Printf(" - %s: %s\n", f.Name, f.Type)
}
}
}
See also: Services, sentinel Integration
Errors
ErrNotFound
var ErrNotFound = errors.New("slush: service not registered")
Returned by Use[T] when no service is registered for type T.
Example:
db, err := slush.Use[Database](ctx)
if errors.Is(err, slush.ErrNotFound) {
// Handle missing service
log.Println("Database service not configured")
}
ErrAccessDenied
var ErrAccessDenied = errors.New("slush: access denied")
Returned by Use[T] when a guard returns an error. The guard's error is joined.
Example:
db, err := slush.Use[Database](ctx)
if errors.Is(err, slush.ErrAccessDenied) {
// Guard rejected - full error includes reason
log.Println(err) // "slush: access denied\nmissing permission: db:write"
// Can also check the guard's specific error
var permErr *PermissionError
if errors.As(err, &permErr) {
log.Printf("Missing: %s", permErr.Permission)
}
}
ErrInvalidKey
var ErrInvalidKey = errors.New("slush: invalid key")
Returned by Services() when an invalid key is provided.
Example:
svcs, err := slush.Services(key)
if errors.Is(err, slush.ErrInvalidKey) {
log.Println("Invalid registry key")
}
Internal Types
These types are not exported but understanding them helps with debugging.
service (interface)
type service interface {
fqdns() (iface, impl string)
guards() []Guard
guardCount() int
}
Internal interface that handle[T] satisfies. Enables heterogeneous storage in the registry map.
handleT (generic struct)
type handle[T any] struct {
g []Guard
interfaceFQDN string
implFQDN string
impl T
}
Internal generic struct that stores a service with full type safety. Satisfies the service interface for storage while preserving T for type-safe retrieval.
sentinel Types
These types come from the sentinel package and appear in ServiceInfo.Metadata.
sentinel.Metadata
type Metadata struct {
FQDN string
TypeName string
PackageName string
Fields []FieldMetadata
Relationships []TypeRelationship
}
Type metadata extracted by sentinel. May be empty if the implementation wasn't scanned.
sentinel.FieldMetadata
type FieldMetadata struct {
Name string
Type string
Kind FieldKind
Tags map[string]string
Index []int
}
Field-level metadata including struct tags.
See also: sentinel Integration, sentinel Documentation
capitan Types
These types come from the capitan package and are used for event handling.
capitan.Signal
Represents an event type. slush exports four signals:
SignalRegisteredSignalAccessedSignalDeniedSignalNotFound
capitan.StringKey
Typed key for string event fields. slush exports:
KeyInterfaceKeyImplKeyError
See also: capitan Integration, capitan Documentation
Next Steps
- API Reference — Function documentation
- Concepts — Mental models
- Architecture — Internal design