// package safe_bool_react -- потокобезопасный булевый признак с реакцией на своё изменение. package safe_bool_react import ( "os" "strings" "sync" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_bool" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_err" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_spec_base" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs/def_txt" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/option" "gitp78su.ipnodns.ru/svi/kern/v4/lev0/result" ) // MSafeBoolReact -- потокобезопасный булевый признак с реакцией на своё изменение. type MSafeBoolReact struct { sync.RWMutex dict map[*def_txt.LTxt]func(*def_bool.MBool) // Словарь обратных вызовов val def_spec_base.Bool } // MutSafeBoolReact -- возвращает новый потокобезопасный булевый признак с реакцией на своё изменение. func MutSafeBoolReact() *MSafeBoolReact { sf := &MSafeBoolReact{ dict: map[*def_txt.LTxt]func(*def_bool.MBool){}, } return sf } // MutSafeBoolReactFromTxt -- возвращает новое потокобезопасное булево с реакцией из строки. func MutSafeBoolReactFromTxt(txtVal *def_txt.LTxt) *result.Result[*MSafeBoolReact] { sf := MutSafeBoolReact() res := sf.FromTxt(txtVal) if res.IsSome() { err := def_err.LetErr("NewSafeBoolReactFromStr(): in parse str(%v), err=\n\t%w", txtVal, res.Some().Get()) return result.ResErr[*MSafeBoolReact](err) } return result.ResOk(sf) } // MutSafeBoolReactFromEnv -- возвращает новое потокобезопасное целое с реакцией из окружения. func MutSafeBoolReactFromEnv(env *def_txt.LTxt) *result.Result[*MSafeBoolReact] { sf := MutSafeBoolReact() res := sf.FromEnv(env) if res.IsSome() { err := def_err.LetErr("NewSafeBoolGetenv(): in parse env(%v), err=\n\t%w", env, res.Some().Get()) return result.ResErr[*MSafeBoolReact](err) } return result.ResOk(sf) } // Delete -- удаляет функцию обратного вызова из наблюдения. func (sf *MSafeBoolReact) Delete(key *def_txt.LTxt) { sf.Lock() defer sf.Unlock() delete(sf.dict, key) } // Add -- добавляет функцию обратного вызова. func (sf *MSafeBoolReact) Add(key *def_txt.LTxt, fn func(*def_bool.MBool)) *result.Result[bool] { sf.Lock() defer sf.Unlock() if key.Get() == "" { err := def_err.LetErr("safeBoolReact.Add(): key is empty") return result.ResErr[bool](err) } _, isOk := sf.dict[key] if isOk { err := def_err.LetErr("safeBoolReact.Add(): key(%v) already exists", key) return result.ResErr[bool](err) } sf.dict[key] = fn return result.ResOk((true)) } // Get -- возвращает хранимый булевый признак. func (sf *MSafeBoolReact) Get() def_spec_base.Bool { sf.RLock() defer sf.RUnlock() return sf.val } // Set -- устанавливает булевый признак. func (sf *MSafeBoolReact) Set() { sf.Lock() defer sf.Unlock() sf.val = true for _, fn := range sf.dict { fn(def_bool.MutBool(true)) } } // Reset -- сбрасывает булевый признак. func (sf *MSafeBoolReact) Reset() { sf.Lock() defer sf.Unlock() sf.val = false for _, fn := range sf.dict { fn(def_bool.MutBool(false)) } } // FromTxt -- получает булево из текста. func (sf *MSafeBoolReact) FromTxt(txtVal *def_txt.LTxt) *option.Option[*def_err.LErr] { _strVal := strings.ToLower(txtVal.String()) sf.Lock() defer sf.Unlock() switch _strVal { case "true": sf.val = true case "false": sf.val = false default: err := def_err.LetErr("safeBoolReact.FromStr(): val(%v) bad", txtVal) return option.NewSome(err) } return option.NewNone[*def_err.LErr]() } // FromEnv -- получает значение из окружения. func (sf *MSafeBoolReact) FromEnv(env *def_txt.LTxt) *option.Option[*def_err.LErr] { strVal := def_spec_base.Txt(os.Getenv(env.String())) res := sf.FromTxt(def_txt.LetTxt(strVal)) if res.IsSome() { err := def_err.LetErr("safeBoolReact.Getenv(): from env %v, err=\n\t%w", env, res.Some().Get()) return option.NewSome(err) } return option.NewNone[*def_err.LErr]() }