use std::any::Any;
use std::sync::Mutex;
use serde::{de::DeserializeOwned, Serialize};
use crate::error::{Error, Result};
pub struct Parameter {
name: String,
inner: Mutex<(Box<dyn Any + Send + Sync>, String)>,
}
impl Parameter {
pub fn new<T: Serialize + DeserializeOwned + Clone + Send + Sync + 'static>(
name: &str,
value: T,
) -> Result<Self> {
let serialized = serde_json::to_string(&value)
.map_err(|e| Error::parameter(name, format!("Failed to serialize: {e}")))?;
Ok(Self {
name: name.to_string(),
inner: Mutex::new((Box::new(value), serialized)),
})
}
pub fn name(&self) -> &str {
&self.name
}
pub fn get_value<T: DeserializeOwned + Clone + Send + Sync + 'static>(&self) -> Result<T> {
let guard = self.inner.lock().unwrap();
let (ref value, ref serialized) = *guard;
if let Some(typed_value) = value.downcast_ref::<T>() {
return Ok(typed_value.clone());
}
let deserialized = serde_json::from_str::<T>(serialized)
.map_err(|e| Error::parameter(&self.name, format!("Failed to deserialize: {e}")))?;
Ok(deserialized)
}
pub fn set_value<T: Serialize + DeserializeOwned + Clone + Send + Sync + 'static>(
&self,
value: T,
) -> Result<()> {
let serialized = serde_json::to_string(&value)
.map_err(|e| Error::parameter(&self.name, format!("Failed to serialize: {e}")))?;
let mut guard = self.inner.lock().unwrap();
*guard = (Box::new(value), serialized);
Ok(())
}
}