118 lines
2.7 KiB
Go
118 lines
2.7 KiB
Go
package judge
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"sync"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Judge represents the interface for custom judge implementations
|
||
|
|
type Judge interface {
|
||
|
|
// Name returns the judge name
|
||
|
|
Name() string
|
||
|
|
// Judge evaluates a task implementation
|
||
|
|
Judge(taskID string, input map[string]interface{}) (map[string]interface{}, error)
|
||
|
|
// Validate checks judge configuration
|
||
|
|
Validate() error
|
||
|
|
}
|
||
|
|
|
||
|
|
// CustomJudgeRegistry manages custom judge implementations
|
||
|
|
type CustomJudgeRegistry struct {
|
||
|
|
mu sync.RWMutex
|
||
|
|
judges map[string]Judge
|
||
|
|
defaultJudge Judge
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewCustomJudgeRegistry creates a new custom judge registry
|
||
|
|
func NewCustomJudgeRegistry() *CustomJudgeRegistry {
|
||
|
|
return &CustomJudgeRegistry{
|
||
|
|
judges: make(map[string]Judge),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Register registers a custom judge
|
||
|
|
func (cjr *CustomJudgeRegistry) Register(name string, judge Judge) error {
|
||
|
|
if name == "" || judge == nil {
|
||
|
|
return fmt.Errorf("name and judge cannot be empty")
|
||
|
|
}
|
||
|
|
|
||
|
|
if err := judge.Validate(); err != nil {
|
||
|
|
return fmt.Errorf("judge validation failed: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
cjr.mu.Lock()
|
||
|
|
defer cjr.mu.Unlock()
|
||
|
|
|
||
|
|
if _, exists := cjr.judges[name]; exists {
|
||
|
|
return fmt.Errorf("judge already registered: %s", name)
|
||
|
|
}
|
||
|
|
|
||
|
|
cjr.judges[name] = judge
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Unregister removes a judge
|
||
|
|
func (cjr *CustomJudgeRegistry) Unregister(name string) error {
|
||
|
|
cjr.mu.Lock()
|
||
|
|
defer cjr.mu.Unlock()
|
||
|
|
|
||
|
|
if _, exists := cjr.judges[name]; !exists {
|
||
|
|
return fmt.Errorf("judge not found: %s", name)
|
||
|
|
}
|
||
|
|
|
||
|
|
delete(cjr.judges, name)
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// Get retrieves a judge by name
|
||
|
|
func (cjr *CustomJudgeRegistry) Get(name string) (Judge, bool) {
|
||
|
|
cjr.mu.RLock()
|
||
|
|
defer cjr.mu.RUnlock()
|
||
|
|
|
||
|
|
judge, exists := cjr.judges[name]
|
||
|
|
return judge, exists
|
||
|
|
}
|
||
|
|
|
||
|
|
// Judge executes judgment with custom judge
|
||
|
|
func (cjr *CustomJudgeRegistry) Judge(name string, taskID string, input map[string]interface{}) (map[string]interface{}, error) {
|
||
|
|
judge, exists := cjr.Get(name)
|
||
|
|
if !exists {
|
||
|
|
return nil, fmt.Errorf("judge not found: %s", name)
|
||
|
|
}
|
||
|
|
|
||
|
|
return judge.Judge(taskID, input)
|
||
|
|
}
|
||
|
|
|
||
|
|
// SetDefaultJudge sets the default judge
|
||
|
|
func (cjr *CustomJudgeRegistry) SetDefaultJudge(judge Judge) error {
|
||
|
|
if err := judge.Validate(); err != nil {
|
||
|
|
return fmt.Errorf("judge validation failed: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
cjr.mu.Lock()
|
||
|
|
defer cjr.mu.Unlock()
|
||
|
|
|
||
|
|
cjr.defaultJudge = judge
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// GetDefaultJudge gets the default judge
|
||
|
|
func (cjr *CustomJudgeRegistry) GetDefaultJudge() Judge {
|
||
|
|
cjr.mu.RLock()
|
||
|
|
defer cjr.mu.RUnlock()
|
||
|
|
|
||
|
|
return cjr.defaultJudge
|
||
|
|
}
|
||
|
|
|
||
|
|
// ListJudges returns all registered judges
|
||
|
|
func (cjr *CustomJudgeRegistry) ListJudges() map[string]Judge {
|
||
|
|
cjr.mu.RLock()
|
||
|
|
defer cjr.mu.RUnlock()
|
||
|
|
|
||
|
|
result := make(map[string]Judge)
|
||
|
|
for name, judge := range cjr.judges {
|
||
|
|
result[name] = judge
|
||
|
|
}
|
||
|
|
|
||
|
|
return result
|
||
|
|
}
|