mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-08-21 10:26:36 +00:00
Uniform framework for bg variable management
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
//! Job runner for futures and async functions
|
||||
|
||||
pub mod vars;
|
||||
pub mod worker;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::error::{Error, OkOrMessage};
|
||||
use crate::migrate::Migrate;
|
||||
use crate::persister::PersisterShared;
|
||||
|
||||
pub struct BgVars {
|
||||
vars: HashMap<&'static str, Box<dyn BgVarTrait>>,
|
||||
}
|
||||
|
||||
impl BgVars {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
vars: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_rw<V, T, GF, SF>(
|
||||
&mut self,
|
||||
p: &PersisterShared<V>,
|
||||
name: &'static str,
|
||||
get_fn: GF,
|
||||
set_fn: SF,
|
||||
) where
|
||||
V: Migrate + Default + Send + Sync,
|
||||
T: FromStr + ToString + Send + Sync + 'static,
|
||||
GF: Fn(&PersisterShared<V>) -> T + Send + Sync + 'static,
|
||||
SF: Fn(&PersisterShared<V>, T) -> Result<(), Error> + Send + Sync + 'static,
|
||||
{
|
||||
let p1 = p.clone();
|
||||
let get_fn = move || get_fn(&p1);
|
||||
|
||||
let p2 = p.clone();
|
||||
let set_fn = move |v| set_fn(&p2, v);
|
||||
|
||||
self.vars.insert(name, Box::new(BgVar { get_fn, set_fn }));
|
||||
}
|
||||
|
||||
pub fn register_ro<V, T, GF>(&mut self, p: &PersisterShared<V>, name: &'static str, get_fn: GF)
|
||||
where
|
||||
V: Migrate + Default + Send + Sync,
|
||||
T: FromStr + ToString + Send + Sync + 'static,
|
||||
GF: Fn(&PersisterShared<V>) -> T + Send + Sync + 'static,
|
||||
{
|
||||
let p1 = p.clone();
|
||||
let get_fn = move || get_fn(&p1);
|
||||
|
||||
let set_fn = move |_| Err(Error::Message(format!("Cannot set value of {}", name)));
|
||||
|
||||
self.vars.insert(name, Box::new(BgVar { get_fn, set_fn }));
|
||||
}
|
||||
|
||||
pub fn get(&self, var: &str) -> Result<String, Error> {
|
||||
Ok(self
|
||||
.vars
|
||||
.get(var)
|
||||
.ok_or_message("variable does not exist")?
|
||||
.get())
|
||||
}
|
||||
|
||||
pub fn get_all(&self) -> Vec<(&'static str, String)> {
|
||||
self.vars.iter().map(|(k, v)| (*k, v.get())).collect()
|
||||
}
|
||||
|
||||
pub fn set(&self, var: &str, val: &str) -> Result<(), Error> {
|
||||
self.vars
|
||||
.get(var)
|
||||
.ok_or_message("variable does not exist")?
|
||||
.set(val)
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
trait BgVarTrait: Send + Sync + 'static {
|
||||
fn get(&self) -> String;
|
||||
fn set(&self, v: &str) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
struct BgVar<T, GF, SF>
|
||||
where
|
||||
T: FromStr + ToString + Send + Sync + 'static,
|
||||
GF: Fn() -> T + Send + Sync + 'static,
|
||||
SF: Fn(T) -> Result<(), Error> + Sync + Send + 'static,
|
||||
{
|
||||
get_fn: GF,
|
||||
set_fn: SF,
|
||||
}
|
||||
|
||||
impl<T, GF, SF> BgVarTrait for BgVar<T, GF, SF>
|
||||
where
|
||||
T: FromStr + ToString + Sync + Send + 'static,
|
||||
GF: Fn() -> T + Sync + Send + 'static,
|
||||
SF: Fn(T) -> Result<(), Error> + Sync + Send + 'static,
|
||||
{
|
||||
fn get(&self) -> String {
|
||||
(self.get_fn)().to_string()
|
||||
}
|
||||
|
||||
fn set(&self, vstr: &str) -> Result<(), Error> {
|
||||
let value = vstr
|
||||
.parse()
|
||||
.map_err(|_| Error::Message(format!("invalid value: {}", vstr)))?;
|
||||
(self.set_fn)(value)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user