
LevelSwitch.pudu
Pudu51 lines1.9 KB
1/** @Log.LevelSwitch.Control — a minimum level changed while running */2module PuduLangLog.LevelSwitch34import Std.Sync as Sync5import PuduLangLog.Domain.Levels as Levels6import PuduLangLog as Log78/** @Log.LevelSwitch.Shared — the level every holder of the switch sees */9export type LevelSwitch = { current: Sync.Cell[Log.Level], lock: Sync.Mutex, listeners: Sync.Cell[Array[fn(Log.Level, Log.Level) -> ()]] }101112export fn create(initial: Log.Level) -> LevelSwitch {13 let none: Array[fn(Log.Level, Log.Level) -> ()] = []14 LevelSwitch{current: Sync.cell(initial), lock: Sync.mutex(), listeners: Sync.cell(none)}15}161718export fn level(control: &LevelSwitch) -> Log.Level {19 match Sync.get(&control.current) {20 case Ok(found) => found21 case Err(_) => Log.Information22 }23}242526export fn allows(control: &LevelSwitch, candidate: Log.Level) -> Bool { Levels.passes(candidate, level(control)) }272829export fn set(control: &LevelSwitch, next: Log.Level) -> () {30 let changed = Sync.withLock(&control.lock, fn() -> Option[Log.Level] {31 let previous = level(control)32 if previous == next { return None }33 let _stored = Sync.set(&control.current, next)34 Some(previous)35 })36 if let Ok(Some(previous)) = changed {37 if let Ok(listeners) = Sync.get(&control.listeners) {38 for listener in listeners { listener(previous, next) }39 }40 }41}424344export fn onChange(control: &LevelSwitch, listener: fn(Log.Level, Log.Level) -> ()) -> () {45 let _registered = Sync.withLock(&control.lock, fn() -> () {46 if let Ok(listeners) = Sync.get(&control.listeners) {47 let _stored = Sync.set(&control.listeners, listeners.push(listener))48 }49 })50}51