use dashmap::DashMap;
use std::fmt;
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use workflow_log::log_info;
pub fn toggle(flag: &Arc<AtomicBool>) -> &'static str {
let v = !flag.load(Ordering::SeqCst);
flag.store(v, Ordering::SeqCst);
if v {
"on"
} else {
"off"
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Track {
Daa = 0,
Balance,
Pending,
Tx,
Utxo,
}
impl FromStr for Track {
type Err = String;
fn from_str(s: &str) -> std::result::Result<Track, String> {
match s {
"daa" => Ok(Track::Daa),
"balance" => Ok(Track::Balance),
"pending" => Ok(Track::Pending),
"tx" => Ok(Track::Tx),
"utxo" => Ok(Track::Utxo),
_ => Err(format!("unknown attribute '{}'", s)),
}
}
}
impl fmt::Display for Track {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Track::Daa => write!(f, "daa"),
Track::Balance => write!(f, "balance"),
Track::Pending => write!(f, "pending"),
Track::Tx => write!(f, "tx"),
Track::Utxo => write!(f, "utxo"),
}
}
}
pub struct Flags(DashMap<Track, Arc<AtomicBool>>);
impl Default for Flags {
fn default() -> Self {
let mut map = DashMap::new();
let iter = [(Track::Daa, false), (Track::Balance, false), (Track::Pending, false), (Track::Tx, false), (Track::Utxo, false)]
.into_iter()
.map(|(flag, default)| (flag, Arc::new(AtomicBool::new(default))));
map.extend(iter);
Flags(map)
}
}
impl Flags {
pub fn map(&self) -> &DashMap<Track, Arc<AtomicBool>> {
&self.0
}
pub fn toggle(&self, track: Track) {
let flag = self.0.get(&track).unwrap();
let v = !flag.load(Ordering::SeqCst);
flag.store(v, Ordering::SeqCst);
let s = if v { "on" } else { "off" };
log_info!("{} is {s}", track.to_string());
}
pub fn get(&self, track: Track) -> bool {
self.0.get(&track).unwrap().load(Ordering::SeqCst)
}
}