// package safe_bool_react -- потокобезопасный булевый признак с реакцией на своё изменение. package safe_bool_react import ( "os" "strings" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_bool" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_err" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_spec_base" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/def_txt" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/safe_mutex" "gitp78su.ipnodns.ru/svi/kern/v4/d0/defs/table/owner" "gitp78su.ipnodns.ru/svi/kern/v4/d0/option" "gitp78su.ipnodns.ru/svi/kern/v4/d0/result" ) // MSafeBoolReact -- потокобезопасный булевый признак с реакцией на своё изменение. type MSafeBoolReact struct { *safe_mutex.MSafeMutex dict map[def_spec_base.Txt]func(def_spec_base.Bool) // Словарь обратных вызовов val *def_bool.MBool } // MutSafeBoolReact -- возвращает новый потокобезопасный булевый признак с реакцией на своё изменение. func MutSafeBoolReact[T def_spec_base.BoolConstraint](owner *owner.LOwner, val T) *MSafeBoolReact { sf := &MSafeBoolReact{ MSafeMutex: safe_mutex.MutSafeMutex(), dict: map[def_spec_base.Txt]func(def_spec_base.Bool){}, val: def_bool.MutBool(owner, val), } return sf } // MutSafeBoolReactFromTxt -- возвращает новое потокобезопасное булево с реакцией из строки. func MutSafeBoolReactFromTxt(owner *owner.LOwner, txtVal *def_txt.LTxt) *result.Result[*MSafeBoolReact] { sf := MutSafeBoolReact(owner, false) 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(owner *owner.LOwner, env *def_txt.LTxt) *result.Result[*MSafeBoolReact] { sf := MutSafeBoolReact(owner, false) 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.Get()) } // Add -- добавляет функцию обратного вызова. func (sf *MSafeBoolReact) Add(key *def_txt.LTxt, fn func(def_spec_base.Bool)) *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.Get()] if isOk { err := def_err.LetErr("safeBoolReact.Add(): key(%v) already exists", key) return result.ResErr[bool](err) } sf.dict[key.Get()] = fn return result.ResOk((true)) } // IsOk -- возвращает хранимый булевый признак. func (sf *MSafeBoolReact) IsOk() def_spec_base.Bool { sf.RLock() defer sf.RUnlock() return sf.val.IsOk() } // IsNot -- возвращает хранимый булевый признак. func (sf *MSafeBoolReact) IsNot() def_spec_base.Bool { sf.RLock() defer sf.RUnlock() return sf.val.IsNot() } // Set -- устанавливает булевый признак. func (sf *MSafeBoolReact) Set() { sf.Lock() defer sf.Unlock() sf.val.Set() for _, fn := range sf.dict { fn(true) } } // Reset -- сбрасывает булевый признак. func (sf *MSafeBoolReact) Reset() { sf.Lock() defer sf.Unlock() sf.val.Reset() for _, fn := range sf.dict { fn(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.Set() case "false": sf.val.Reset() 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]() }