Files
SafeLine/management/webserver/stubs/chaitin.cn/dev/go/settings/settings.go
T
Binbim 3178b8c448 feat: add compiled binaries and stub build system
- Compiled webserver and tcontrollerd for Linux amd64
- Added CGo stubs to build without FVM library
- Added private module stubs (errors, log, settings)
- Added proto stubs for gRPC
- Added install.sh deployment script
- Fixed auth.go type error and TOTP clock skew bypass
2026-07-05 02:46:26 +08:00

152 lines
2.9 KiB
Go

package settings
import (
"os"
"strconv"
)
var globalSetting *Setting
type Setting struct {
values map[string]interface{}
}
func New(configPath string) (*Setting, error) {
s := &Setting{
values: make(map[string]interface{}),
}
// Try to load from environment variables with prefix
prefix := "SAFELINE_"
for _, env := range os.Environ() {
key := env
val := ""
for i := 0; i < len(env); i++ {
if env[i] == '=' {
key = env[:i]
val = env[i+1:]
break
}
}
if len(key) > len(prefix) && key[:len(prefix)] == prefix {
s.values[key[len(prefix):]] = val
}
}
// Also load from config file if it exists
if _, err := os.Stat(configPath); err == nil {
data, err := os.ReadFile(configPath)
if err == nil {
// Simple line-by-line parsing for YAML-like config
lines := splitLines(string(data))
for _, line := range lines {
if len(line) == 0 || line[0] == '#' {
continue
}
for i := 0; i < len(line); i++ {
if line[i] == ':' {
key := trimSpace(line[:i])
val := trimSpace(line[i+1:])
if len(val) >= 2 && val[0] == '"' && val[len(val)-1] == '"' {
val = val[1 : len(val)-1]
}
s.values[key] = val
break
}
}
}
}
}
globalSetting = s
return s, nil
}
func Unmarshal(key string, dest interface{}) error {
if globalSetting == nil {
return nil
}
return globalSetting.Unmarshal(key, dest)
}
func (s *Setting) Unmarshal(key string, dest interface{}) error {
if val, ok := s.values[key]; ok {
switch v := dest.(type) {
case *string:
*v, _ = val.(string)
case *int:
if str, ok := val.(string); ok {
*v, _ = strconv.Atoi(str)
}
case *bool:
if str, ok := val.(string); ok {
*v = str == "true" || str == "1"
}
}
}
return nil
}
func (s *Setting) Get(key string, defaultVal interface{}) interface{} {
if val, ok := s.values[key]; ok {
return val
}
return defaultVal
}
func (s *Setting) GetString(key, defaultVal string) string {
if val, ok := s.values[key]; ok {
if str, ok := val.(string); ok {
return str
}
}
return defaultVal
}
func (s *Setting) GetInt(key string, defaultVal int) int {
if val, ok := s.values[key]; ok {
if str, ok := val.(string); ok {
if i, err := strconv.Atoi(str); err == nil {
return i
}
}
}
return defaultVal
}
func (s *Setting) GetBool(key string, defaultVal bool) bool {
if val, ok := s.values[key]; ok {
if str, ok := val.(string); ok {
return str == "true" || str == "1"
}
}
return defaultVal
}
func splitLines(s string) []string {
var lines []string
start := 0
for i := 0; i < len(s); i++ {
if s[i] == '\n' {
lines = append(lines, s[start:i])
start = i + 1
}
}
if start < len(s) {
lines = append(lines, s[start:])
}
return lines
}
func trimSpace(s string) string {
start := 0
end := len(s)
for start < end && (s[start] == ' ' || s[start] == '\t') {
start++
}
for end > start && (s[end-1] == ' ' || s[end-1] == '\t') {
end--
}
return s[start:end]
}