safe_bool_react.go 3.6 KB

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