safe_bool_react.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // package safe_bool_react -- потокобезопасный булевый признак с реакцией на своё изменение.
  2. package safe_bool_react
  3. import (
  4. "os"
  5. "strings"
  6. "sync"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/defs"
  9. )
  10. // safeBoolReact -- потокобезопасный булевый признак с реакцией на своё изменение.
  11. type safeBoolReact struct {
  12. sync.RWMutex
  13. dict map[*lev0.LTxt]func(*lev0.MBool) // Словарь обратных вызовов
  14. val defs.Bool
  15. }
  16. // NewSafeBoolReact -- возвращает новый потокобезопасный булевый признак с реакцией на своё изменение.
  17. func NewSafeBoolReact() lev0.ISafeBoolReact {
  18. sf := &safeBoolReact{
  19. dict: map[*lev0.LTxt]func(*lev0.MBool){},
  20. }
  21. return sf
  22. }
  23. // NewSafeBoolReactFromStr -- возвращает новое потокобезопасное булево с реакцией из строки.
  24. func NewSafeBoolReactFromStr(strVal *lev0.LTxt) *lev0.Result[lev0.ISafeBoolReact] {
  25. sf := NewSafeBoolReact()
  26. res := sf.FromStr(strVal)
  27. if res.IsSome() {
  28. err := lev0.LetErr("NewSafeBoolReactFromStr(): in parse str(%v), err=\n\t%w",
  29. strVal, res.Some().Get())
  30. return lev0.ResErr[lev0.ISafeBoolReact](err)
  31. }
  32. return lev0.ResOk(sf)
  33. }
  34. // NewSafeBoolGetenv -- возвращает новое потокобезопасное целое с реакцией из окружения.
  35. func NewSafeBoolGetenv(env *lev0.LTxt) *lev0.Result[lev0.ISafeBoolReact] {
  36. sf := NewSafeBoolReact()
  37. res := sf.Getenv(env)
  38. if res.IsSome() {
  39. err := lev0.LetErr("NewSafeBoolGetenv(): in parse env(%v), err=\n\t%w", env, res.Some().Get())
  40. return lev0.ResErr[lev0.ISafeBoolReact](err)
  41. }
  42. return lev0.ResOk(sf)
  43. }
  44. // Delete -- удаляет функцию обратного вызова из наблюдения.
  45. func (sf *safeBoolReact) Delete(key *lev0.LTxt) {
  46. sf.Lock()
  47. defer sf.Unlock()
  48. delete(sf.dict, key)
  49. }
  50. // Add -- добавляет функцию обратного вызова.
  51. func (sf *safeBoolReact) Add(key *lev0.LTxt, fn func(*lev0.MBool)) *lev0.Result[bool] {
  52. sf.Lock()
  53. defer sf.Unlock()
  54. if key.Get() == "" {
  55. err := lev0.LetErr("safeBoolReact.Add(): key is empty")
  56. return lev0.ResErr[bool](err)
  57. }
  58. _, isOk := sf.dict[key]
  59. if isOk {
  60. err := lev0.LetErr("safeBoolReact.Add(): key(%v) already exists", key)
  61. return lev0.ResErr[bool](err)
  62. }
  63. sf.dict[key] = fn
  64. return lev0.ResOk((true))
  65. }
  66. // Get -- возвращает хранимый булевый признак.
  67. func (sf *safeBoolReact) Get() lev0.Bool {
  68. sf.RLock()
  69. defer sf.RUnlock()
  70. return sf.val
  71. }
  72. // Set -- устанавливает булевый признак.
  73. func (sf *safeBoolReact) Set() {
  74. sf.Lock()
  75. defer sf.Unlock()
  76. sf.val = true
  77. for _, fn := range sf.dict {
  78. fn(lev0.MutBool(true))
  79. }
  80. }
  81. // Reset -- сбрасывает булевый признак.
  82. func (sf *safeBoolReact) Reset() {
  83. sf.Lock()
  84. defer sf.Unlock()
  85. sf.val = false
  86. for _, fn := range sf.dict {
  87. fn(lev0.MutBool(false))
  88. }
  89. }
  90. // FromStr -- получает число из строки.
  91. func (sf *safeBoolReact) FromStr(strVal *lev0.LTxt) *lev0.Option[*lev0.LErr] {
  92. _strVal := strings.ToLower(strVal.String())
  93. sf.Lock()
  94. defer sf.Unlock()
  95. switch _strVal {
  96. case "true":
  97. sf.val = true
  98. case "false":
  99. sf.val = false
  100. default:
  101. err := lev0.LetErr("safeBoolReact.FromStr(): val(%v) bad", strVal)
  102. return lev0.NewSome(err)
  103. }
  104. return lev0.NewNone[*lev0.LErr]()
  105. }
  106. // Getenv -- получает значение из окружения.
  107. func (sf *safeBoolReact) Getenv(env *lev0.LTxt) *lev0.Option[*lev0.LErr] {
  108. strVal := lev0.ATxt(os.Getenv(env.String()))
  109. res := sf.FromStr(lev0.LetTxt(strVal))
  110. if res.IsSome() {
  111. err := lev0.LetErr("safeBoolReact.Getenv(): from env %v, err=\n\t%w",
  112. env, res.Some().Get())
  113. return lev0.NewSome[*lev0.LErr](err)
  114. }
  115. return lev0.NewNone[*lev0.LErr]()
  116. }