safe_bool_react.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // package safe_bool_react -- потокобезопасный булевый признак с реакцией на своё изменение.
  2. package safe_bool_react
  3. import (
  4. "fmt"
  5. "os"
  6. "strings"
  7. "sync"
  8. mL0 "gitp78su.ipnodns.ru/svi/kern/v4/lev0"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/etypes/ebool"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
  11. mKs "gitp78su.ipnodns.ru/svi/kern/v4/lev0/kspec"
  12. )
  13. // safeBoolReact -- потокобезопасный булевый признак с реакцией на своё изменение.
  14. type safeBoolReact struct {
  15. sync.RWMutex
  16. dict map[string]func(kspec.EBoolMut) // Словарь обратных вызовов
  17. val bool
  18. }
  19. // NewSafeBoolReact -- возвращает новый потокобезопасный булевый признак с реакцией на своё изменение.
  20. func NewSafeBoolReact() mKs.ISafeBoolReact {
  21. sf := &safeBoolReact{
  22. dict: map[string]func(kspec.EBoolMut){},
  23. }
  24. return sf
  25. }
  26. // NewSafeBoolReactFromStr -- возвращает новое потокобезопасное булево с реакцией из строки.
  27. func NewSafeBoolReactFromStr(strVal string) mL0.IResult[mKs.ISafeBoolReact] {
  28. sf := NewSafeBoolReact()
  29. res := sf.FromStr(strVal)
  30. if res.IsErr() {
  31. err := fmt.Errorf("NewSafeBoolReactFromStr(): in parse str(%v), err=\n\t%w", strVal, res.Err())
  32. return mL0.NewErr[mKs.ISafeBoolReact](err)
  33. }
  34. return mL0.NewOk(sf)
  35. }
  36. // NewSafeBoolGetenv -- возвращает новое потокобезопасное целое с реакцией из окружения.
  37. func NewSafeBoolGetenv(env string) mL0.IResult[mKs.ISafeBoolReact] {
  38. sf := NewSafeBoolReact()
  39. res := sf.Getenv(env)
  40. if res.IsErr() {
  41. err := fmt.Errorf("NewSafeBoolGetenv(): in parse env(%v), err=\n\t%w", env, res.Err())
  42. return mL0.NewErr[mKs.ISafeBoolReact](err)
  43. }
  44. return mL0.NewOk(sf)
  45. }
  46. // Delete -- удаляет функцию обратного вызова из наблюдения.
  47. func (sf *safeBoolReact) Delete(key string) {
  48. sf.Lock()
  49. defer sf.Unlock()
  50. delete(sf.dict, key)
  51. }
  52. // Add -- добавляет функцию обратного вызова.
  53. func (sf *safeBoolReact) Add(key string, fn func(kspec.EBoolMut)) mL0.IResult[kspec.EBool] {
  54. sf.Lock()
  55. defer sf.Unlock()
  56. if key == "" {
  57. return mL0.NewErr[kspec.EBool](fmt.Errorf("safeBoolReact.Add(): key is empty"))
  58. }
  59. _, isOk := sf.dict[key]
  60. if isOk {
  61. return mL0.NewErr[kspec.EBool](fmt.Errorf("safeBoolReact.Add(): key(%v) already exists", key))
  62. }
  63. sf.dict[key] = fn
  64. return mL0.NewOk(ebool.NewEBool(true))
  65. }
  66. // Get -- возвращает хранимый булевый признак.
  67. func (sf *safeBoolReact) Get() 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(ebool.NewEBoolMut(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(ebool.NewEBoolMut(false))
  88. }
  89. }
  90. // FromStr -- получает число из строки.
  91. func (sf *safeBoolReact) FromStr(strVal string) mL0.IResult[kspec.EBool] {
  92. strVal = strings.ToLower(strVal)
  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. return mL0.NewErr[kspec.EBool](fmt.Errorf("safeBoolReact.FromStr(): val(%v) bad", strVal))
  102. }
  103. return mL0.NewOk(ebool.NewEBool(sf.val))
  104. }
  105. // Getenv -- получает значение из окружения.
  106. func (sf *safeBoolReact) Getenv(env string) mL0.IResult[kspec.EBool] {
  107. strVal := os.Getenv(env)
  108. res := sf.FromStr(strVal)
  109. if res.IsErr() {
  110. err := fmt.Errorf("safeBoolReact.Getenv(): from env %v, err=\n\t%w", env, res.Err())
  111. return mL0.NewErr[kspec.EBool](err)
  112. }
  113. return res
  114. }