--- /dev/null
+#[perlmod::package(name = "PVE::RS::Notify")]
+mod export {
+ use anyhow::{bail, Error};
+ use perlmod::Value;
+
+ use std::sync::Mutex;
+
+ use proxmox_notify::Config;
+
+ pub struct NotificationConfig {
+ config: Mutex<Config>,
+ }
+
+ perlmod::declare_magic!(Box<NotificationConfig> : &NotificationConfig as "PVE::RS::Notify");
+
+ /// Support `dclone` so this can be put into the `ccache` of `PVE::Cluster`.
+ #[export(name = "STORABLE_freeze", raw_return)]
+ fn storable_freeze(
+ #[try_from_ref] this: &NotificationConfig,
+ cloning: bool,
+ ) -> Result<Value, Error> {
+ if !cloning {
+ bail!("freezing Notification config not supported!");
+ }
+
+ let mut cloned = Box::new(NotificationConfig {
+ config: Mutex::new(this.config.lock().unwrap().clone()),
+ });
+ let value = Value::new_pointer::<NotificationConfig>(&mut *cloned);
+ let _perl = Box::leak(cloned);
+ Ok(value)
+ }
+
+ /// Instead of `thaw` we implement `attach` for `dclone`.
+ #[export(name = "STORABLE_attach", raw_return)]
+ fn storable_attach(
+ #[raw] class: Value,
+ cloning: bool,
+ #[raw] serialized: Value,
+ ) -> Result<Value, Error> {
+ if !cloning {
+ bail!("STORABLE_attach called with cloning=false");
+ }
+ let data = unsafe { Box::from_raw(serialized.pv_raw::<NotificationConfig>()?) };
+ Ok(perlmod::instantiate_magic!(&class, MAGIC => data))
+ }
+
+ #[export(raw_return)]
+ fn parse_config(
+ #[raw] class: Value,
+ raw_config: &[u8],
+ raw_private_config: &[u8],
+ ) -> Result<Value, Error> {
+ let raw_config = std::str::from_utf8(raw_config)?;
+ let raw_private_config = std::str::from_utf8(raw_private_config)?;
+
+ Ok(perlmod::instantiate_magic!(&class, MAGIC => Box::new(
+ NotificationConfig {
+ config: Mutex::new(Config::new(raw_config, raw_private_config)?)
+ }
+ )))
+ }
+
+ #[export]
+ fn write_config(#[try_from_ref] this: &NotificationConfig) -> Result<(String, String), Error> {
+ Ok(this.config.lock().unwrap().write()?)
+ }
+
+ #[export]
+ fn digest(#[try_from_ref] this: &NotificationConfig) -> String {
+ let config = this.config.lock().unwrap();
+ hex::encode(config.digest())
+ }
+}