// package safe_bool_react -- потокобезопасный булевый признак с реакцией на своё изменение. package safe_bool_react import ( "os" "strings" "sync" mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/core_spec" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool" ) // safeBoolReact -- потокобезопасный булевый признак с реакцией на своё изменение. type safeBoolReact struct { sync.RWMutex dict map[defs.ITxtFix]func(core_spec.EBoolMut) // Словарь обратных вызовов val bool } // NewSafeBoolReact -- возвращает новый потокобезопасный булевый признак с реакцией на своё изменение. func NewSafeBoolReact() core_spec.ISafeBoolReact { sf := &safeBoolReact{ dict: map[defs.ITxtFix]func(core_spec.EBoolMut){}, } return sf } // NewSafeBoolReactFromStr -- возвращает новое потокобезопасное булево с реакцией из строки. func NewSafeBoolReactFromStr(strVal defs.ITxtFix) mL0.IResult[core_spec.ISafeBoolReact] { sf := NewSafeBoolReact() res := sf.FromStr(strVal) if res.IsErr() { err := defs.Err("NewSafeBoolReactFromStr(): in parse str(%v), err=\n\t%w", strVal, res.Err()) return mL0.NewErr[core_spec.ISafeBoolReact](err) } return mL0.NewOk(sf) } // NewSafeBoolGetenv -- возвращает новое потокобезопасное целое с реакцией из окружения. func NewSafeBoolGetenv(env defs.ITxtFix) mL0.IResult[core_spec.ISafeBoolReact] { sf := NewSafeBoolReact() res := sf.Getenv(env) if res.IsErr() { err := defs.Err("NewSafeBoolGetenv(): in parse env(%v), err=\n\t%w", env, res.Err()) return mL0.NewErr[core_spec.ISafeBoolReact](err) } return mL0.NewOk(sf) } // Delete -- удаляет функцию обратного вызова из наблюдения. func (sf *safeBoolReact) Delete(key defs.ITxtFix) { sf.Lock() defer sf.Unlock() delete(sf.dict, key) } // Add -- добавляет функцию обратного вызова. func (sf *safeBoolReact) Add(key defs.ITxtFix, fn func(core_spec.EBoolMut)) mL0.IResult[core_spec.EBool] { sf.Lock() defer sf.Unlock() if key.Get() == "" { err := defs.Err("safeBoolReact.Add(): key is empty") return mL0.NewErr[core_spec.EBool](err) } _, isOk := sf.dict[key] if isOk { err := defs.Err("safeBoolReact.Add(): key(%v) already exists", key) return mL0.NewErr[core_spec.EBool](err) } sf.dict[key] = fn return mL0.NewOk(ebool.NewEBool(true)) } // Get -- возвращает хранимый булевый признак. func (sf *safeBoolReact) Get() bool { sf.RLock() defer sf.RUnlock() return sf.val } // Set -- устанавливает булевый признак. func (sf *safeBoolReact) Set() { sf.Lock() defer sf.Unlock() sf.val = true for _, fn := range sf.dict { fn(ebool.NewEBoolMut(true)) } } // Reset -- сбрасывает булевый признак. func (sf *safeBoolReact) Reset() { sf.Lock() defer sf.Unlock() sf.val = false for _, fn := range sf.dict { fn(ebool.NewEBoolMut(false)) } } // FromStr -- получает число из строки. func (sf *safeBoolReact) FromStr(strVal defs.ITxtFix) core_spec.IResult[core_spec.EBool] { _strVal := strings.ToLower(strVal.String()) sf.Lock() defer sf.Unlock() switch _strVal { case "true": sf.val = true case "false": sf.val = false default: err := defs.Err("safeBoolReact.FromStr(): val(%v) bad", strVal) return mL0.NewErr[core_spec.EBool](err) } return mL0.NewOk(ebool.NewEBool(sf.val)) } // Getenv -- получает значение из окружения. func (sf *safeBoolReact) Getenv(env defs.ITxtFix) mL0.IResult[core_spec.EBool] { strVal := defs.ATxt(os.Getenv(env.String())) res := sf.FromStr(defs.Txt(strVal)) if res.IsErr() { err := defs.Err("safeBoolReact.Getenv(): from env %v, err=\n\t%w", env, res.Err()) return mL0.NewErr[core_spec.EBool](err) } return res }