safe_bool_react.go 4.1 KB

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