Skip to main content

kodik_parser/
state.rs

1use std::sync::{
2    Arc, LazyLock,
3    atomic::{AtomicBool, AtomicU8, Ordering},
4};
5
6use arc_swap::ArcSwap;
7use tokio::sync::Notify;
8
9pub static KODIK_STATE: LazyLock<KodikState> = LazyLock::new(KodikState::default);
10
11#[derive(Debug, Default)]
12pub struct KodikState {
13    endpoint: ArcSwap<String>,
14    shift: AtomicU8,
15    notify: Notify,
16    updating: AtomicBool,
17}
18
19impl KodikState {
20    pub fn shift(&self) -> u8 {
21        self.shift.load(Ordering::Relaxed)
22    }
23
24    pub fn set_shift(&self, shift: u8) {
25        self.shift.store(shift, Ordering::Relaxed);
26    }
27
28    pub fn endpoint(&self) -> Arc<String> {
29        self.endpoint.load_full()
30    }
31
32    pub fn set_endpoint(&self, endpoint: String) {
33        self.endpoint.store(Arc::new(endpoint));
34    }
35
36    pub(crate) fn clear_endpoint(&self) {
37        self.set_endpoint(String::new());
38    }
39
40    pub(crate) fn try_begin_update(&self) -> bool {
41        !self.updating.swap(true, Ordering::AcqRel)
42    }
43
44    pub(crate) fn finish_update(&self, endpoint: String) {
45        self.set_endpoint(endpoint);
46        self.updating.store(false, Ordering::Release);
47        self.notify.notify_waiters();
48    }
49
50    pub(crate) async fn wait_for_update(&self) {
51        self.notify.notified().await;
52    }
53}