Files
preface-tools/internal/tools/tool.go
T
2026-07-12 02:56:51 +08:00

58 lines
1.3 KiB
Go

package tools
import (
"context"
"errors"
"net/http"
"sort"
"sync"
)
type Definition struct{ Key, Name, Description string }
type Tool interface {
Definition() Definition
StudentHandler() http.Handler
}
type InstructorTool interface{ InstructorHandler() http.Handler }
type Runner interface{ Run(context.Context) error }
var ErrNotFound = errors.New("tool not found")
type Registry struct {
mu sync.RWMutex
tools map[string]Tool
}
func NewRegistry() *Registry { return &Registry{tools: make(map[string]Tool)} }
func (r *Registry) Register(t Tool) error {
if t == nil || t.Definition().Key == "" {
return errors.New("tool key is required")
}
r.mu.Lock()
defer r.mu.Unlock()
if _, ok := r.tools[t.Definition().Key]; ok {
return errors.New("duplicate tool key")
}
r.tools[t.Definition().Key] = t
return nil
}
func (r *Registry) Get(key string) (Tool, error) {
r.mu.RLock()
defer r.mu.RUnlock()
t, ok := r.tools[key]
if !ok {
return nil, ErrNotFound
}
return t, nil
}
func (r *Registry) List() []Tool {
r.mu.RLock()
defer r.mu.RUnlock()
out := make([]Tool, 0, len(r.tools))
for _, t := range r.tools {
out = append(out, t)
}
sort.Slice(out, func(i, j int) bool { return out[i].Definition().Name < out[j].Definition().Name })
return out
}