eq2go/internal/common/variables.go

262 lines
6.2 KiB
Go

package common
import (
"fmt"
"strings"
"sync"
)
// Variable represents a configuration variable with name, value, and optional comment
type Variable struct {
name string
value string
comment string
}
// NewVariable creates a new variable
func NewVariable(name, value, comment string) *Variable {
return &Variable{
name: name,
value: value,
comment: comment,
}
}
// GetName returns the variable name
func (v *Variable) GetName() string {
return v.name
}
// GetValue returns the variable value
func (v *Variable) GetValue() string {
return v.value
}
// GetComment returns the variable comment
func (v *Variable) GetComment() string {
return v.comment
}
// GetNameValuePair returns the name and value as a single string
func (v *Variable) GetNameValuePair() string {
return fmt.Sprintf("%s %s", v.name, v.value)
}
// SetValue updates the variable value
func (v *Variable) SetValue(value string) {
v.value = value
}
// Variables manages a collection of configuration variables
type Variables struct {
variables map[string]*Variable
mutex sync.RWMutex
}
// NewVariables creates a new variables manager
func NewVariables() *Variables {
return &Variables{
variables: make(map[string]*Variable),
}
}
// AddVariable adds a variable to the collection
func (v *Variables) AddVariable(variable *Variable) {
v.mutex.Lock()
defer v.mutex.Unlock()
v.variables[variable.name] = variable
}
// FindVariable finds a variable by exact name
func (v *Variables) FindVariable(name string) *Variable {
v.mutex.RLock()
defer v.mutex.RUnlock()
return v.variables[name]
}
// GetVariable is an alias for FindVariable for convenience
func (v *Variables) GetVariable(name string) *Variable {
return v.FindVariable(name)
}
// GetVariables returns all variables that contain the partial name
func (v *Variables) GetVariables(partialName string) []*Variable {
v.mutex.RLock()
defer v.mutex.RUnlock()
results := make([]*Variable, 0)
partialLower := strings.ToLower(partialName)
for name, variable := range v.variables {
if strings.Contains(strings.ToLower(name), partialLower) {
results = append(results, variable)
}
}
return results
}
// GetAllVariables returns all variables in the collection
func (v *Variables) GetAllVariables() map[string]*Variable {
v.mutex.RLock()
defer v.mutex.RUnlock()
// Return a copy to prevent external modification
result := make(map[string]*Variable)
for name, variable := range v.variables {
result[name] = variable
}
return result
}
// GetVariableNames returns all variable names
func (v *Variables) GetVariableNames() []string {
v.mutex.RLock()
defer v.mutex.RUnlock()
names := make([]string, 0, len(v.variables))
for name := range v.variables {
names = append(names, name)
}
return names
}
// SetVariable sets or updates a variable value
func (v *Variables) SetVariable(name, value string) {
v.mutex.Lock()
defer v.mutex.Unlock()
if variable, exists := v.variables[name]; exists {
variable.SetValue(value)
} else {
// Create new variable if it doesn't exist
v.variables[name] = NewVariable(name, value, "")
}
}
// DeleteVariable removes a variable by name
func (v *Variables) DeleteVariable(name string) bool {
v.mutex.Lock()
defer v.mutex.Unlock()
if _, exists := v.variables[name]; exists {
delete(v.variables, name)
return true
}
return false
}
// ClearVariables removes all variables
func (v *Variables) ClearVariables() {
v.mutex.Lock()
defer v.mutex.Unlock()
v.variables = make(map[string]*Variable)
}
// Count returns the number of variables
func (v *Variables) Count() int {
v.mutex.RLock()
defer v.mutex.RUnlock()
return len(v.variables)
}
// HasVariable checks if a variable exists
func (v *Variables) HasVariable(name string) bool {
v.mutex.RLock()
defer v.mutex.RUnlock()
_, exists := v.variables[name]
return exists
}
// GetVariableValue returns just the value of a variable, or empty string if not found
func (v *Variables) GetVariableValue(name string) string {
if variable := v.FindVariable(name); variable != nil {
return variable.GetValue()
}
return ""
}
// GetVariableValueWithDefault returns the value of a variable, or a default if not found
func (v *Variables) GetVariableValueWithDefault(name, defaultValue string) string {
if variable := v.FindVariable(name); variable != nil {
return variable.GetValue()
}
return defaultValue
}
// GetVariableAsInt attempts to parse a variable value as an integer
func (v *Variables) GetVariableAsInt(name string, defaultValue int) int {
if variable := v.FindVariable(name); variable != nil {
var intValue int
if _, err := fmt.Sscanf(variable.GetValue(), "%d", &intValue); err == nil {
return intValue
}
}
return defaultValue
}
// GetVariableAsFloat attempts to parse a variable value as a float
func (v *Variables) GetVariableAsFloat(name string, defaultValue float64) float64 {
if variable := v.FindVariable(name); variable != nil {
var floatValue float64
if _, err := fmt.Sscanf(variable.GetValue(), "%f", &floatValue); err == nil {
return floatValue
}
}
return defaultValue
}
// GetVariableAsBool attempts to parse a variable value as a boolean
func (v *Variables) GetVariableAsBool(name string, defaultValue bool) bool {
if variable := v.FindVariable(name); variable != nil {
value := strings.ToLower(variable.GetValue())
switch value {
case "true", "1", "yes", "on", "enabled":
return true
case "false", "0", "no", "off", "disabled":
return false
}
}
return defaultValue
}
// Clone creates a deep copy of the variables collection
func (v *Variables) Clone() *Variables {
v.mutex.RLock()
defer v.mutex.RUnlock()
newVars := NewVariables()
for name, variable := range v.variables {
newVar := NewVariable(variable.name, variable.value, variable.comment)
newVars.variables[name] = newVar
}
return newVars
}
// Merge merges another Variables collection into this one
// If overwrite is true, existing variables will be overwritten
func (v *Variables) Merge(other *Variables, overwrite bool) {
if other == nil {
return
}
v.mutex.Lock()
defer v.mutex.Unlock()
otherVars := other.GetAllVariables()
for name, variable := range otherVars {
if _, exists := v.variables[name]; !exists || overwrite {
v.variables[name] = NewVariable(variable.name, variable.value, variable.comment)
}
}
}