initial commit
This commit is contained in:
115
internal/functions/registry.go
Normal file
115
internal/functions/registry.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package functions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"reichard.io/poiesis/internal/tsconvert"
|
||||
)
|
||||
|
||||
var (
|
||||
functionRegistry = make(map[string]Function)
|
||||
registryMutex sync.RWMutex
|
||||
)
|
||||
|
||||
func registerFunction[A Args, R any](name string, isAsync bool, fn GoFunc[A, R]) {
|
||||
// Lock Registry
|
||||
registryMutex.Lock()
|
||||
defer registryMutex.Unlock()
|
||||
|
||||
// Validate Args Type
|
||||
tType := reflect.TypeFor[A]()
|
||||
if tType.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("function %s: argument must be a struct type, got %v", name, tType))
|
||||
}
|
||||
|
||||
// Collect Types and Generate Definition
|
||||
fnType := reflect.TypeOf(fn)
|
||||
types := tsconvert.CollectTypes(tType, fnType)
|
||||
definition := tsconvert.GenerateFunctionDecl(name, tType, fnType, isAsync)
|
||||
|
||||
// Register Function
|
||||
functionRegistry[name] = &functionImpl[A, R]{
|
||||
name: name,
|
||||
fn: fn,
|
||||
types: types.All(),
|
||||
definition: definition,
|
||||
isAsync: isAsync,
|
||||
}
|
||||
}
|
||||
|
||||
func GetFunctionDeclarations() string {
|
||||
// Lock Registry
|
||||
registryMutex.RLock()
|
||||
defer registryMutex.RUnlock()
|
||||
|
||||
// Collect Type Definitions
|
||||
typeDefinitions := make(map[string]bool)
|
||||
var typeDefs []string
|
||||
var functionDecls []string
|
||||
|
||||
for _, fn := range functionRegistry {
|
||||
for _, t := range fn.Types() {
|
||||
if !typeDefinitions[t] {
|
||||
typeDefinitions[t] = true
|
||||
typeDefs = append(typeDefs, t)
|
||||
}
|
||||
}
|
||||
functionDecls = append(functionDecls, fn.Definition())
|
||||
}
|
||||
|
||||
// Build Result
|
||||
result := strings.Join(typeDefs, "\n\n")
|
||||
if len(result) > 0 && len(functionDecls) > 0 {
|
||||
result += "\n\n"
|
||||
}
|
||||
result += strings.Join(functionDecls, "\n")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// GetTypeDeclarations returns all type declarations from all registered functions.
|
||||
// This is used for aggregating types across multiple functions.
|
||||
func GetTypeDeclarations() map[string]string {
|
||||
// Lock Registry
|
||||
registryMutex.RLock()
|
||||
defer registryMutex.RUnlock()
|
||||
|
||||
// Collect All Types
|
||||
allTypes := make(map[string]string)
|
||||
for _, fn := range functionRegistry {
|
||||
for name, def := range fn.Types() {
|
||||
if existing, ok := allTypes[name]; ok && existing != def {
|
||||
// Type Conflict Detected - Skip
|
||||
continue
|
||||
}
|
||||
allTypes[name] = def
|
||||
}
|
||||
}
|
||||
return allTypes
|
||||
}
|
||||
|
||||
func GetRegisteredFunctions() map[string]Function {
|
||||
// Lock Registry
|
||||
registryMutex.RLock()
|
||||
defer registryMutex.RUnlock()
|
||||
|
||||
// Copy Registry
|
||||
result := make(map[string]Function, len(functionRegistry))
|
||||
for k, v := range functionRegistry {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func RegisterFunction[T Args, R any](name string, fn GoFunc[T, R]) {
|
||||
// Register Sync Function
|
||||
registerFunction(name, false, fn)
|
||||
}
|
||||
|
||||
func RegisterAsyncFunction[T Args, R any](name string, fn GoFunc[T, R]) {
|
||||
// Register Async Function
|
||||
registerFunction(name, true, fn)
|
||||
}
|
||||
Reference in New Issue
Block a user