//! `Executable` is a property to execute a closure use anyhow::Result; use std::sync::{Arc, RwLock}; use crate::prelude::*; /// `Executable` holds a closure which can be executed pub struct Executable { gui_handler: Arc, callback: RwLock Result<()> + Send + Sync>>>, } impl Executable { /// Factory method for `Executable`, returns `Arc` pub fn new(gui_handler: &Arc) -> Arc { Arc::new(Executable { gui_handler: gui_handler.clone(), callback: RwLock::new(None), }) } /// Set callback closure /// /// # Arguments /// /// * `callback` is a `Option` closure pub fn set_callback(&self, callback: impl Into>) where F: Fn(I) -> Result<()> + Send + Sync + 'static, { let mut function = self.callback.write().unwrap(); match callback.into() { Some(f) => *function = Some(Arc::new(f)), None => *function = None, } } /// Execute the callback closure if possible pub fn execute(&self, input: I) -> Result<()> { if let Some(callback) = self.callback.read().unwrap().as_ref() { let callback = callback.clone(); self.gui_handler.add_callback(move || (callback)(input)); } Ok(()) } }