Plugis
FileExtPlugin
A FileExtPlugin
takes a PathBuf
as parameter and returns a RuntimeNode
. It also defines its target file extensions.
#![allow(unused)] fn main() { #[derive(FileExtPlugin)] pub struct DefaultFileExtPlugin {} #[file_ext_plugin(runtime = "default_runtime")] impl FileExtPlugin for DefaultFileExtPlugin { async fn new() -> Result<Self> where Self: Sized, { Ok(DefaultFileExtPlugin {}) } fn target(&self) -> Vec<String> { vec!["so".to_string(), "dylib".to_string(), "dll".to_string()] } async fn load( &self, path: std::path::PathBuf, inputs: Inputs, outputs: Outputs, queries: Queries, queryables: Queryables, configuration: serde_yml::Value, ) -> Result<iridis_runtime_core::prelude::RuntimeNode> { match path.extension() { Some(ext) => { if ext == std::env::consts::DLL_EXTENSION { let path_buf = path.clone(); let (library, constructor) = tokio::task::spawn_blocking(move || { let library = unsafe { #[cfg(target_family = "unix")] let library = libloading::os::unix::Library::open( Some(path_buf.clone()), libloading::os::unix::RTLD_NOW | libloading::os::unix::RTLD_GLOBAL, ) .wrap_err(format!("Failed to load path {:?}", path_buf))?; #[cfg(not(target_family = "unix"))] let library = Library::new(path_buf.clone()) .wrap_err(format!("Failed to load path {:?}", path_buf))?; library }; let constructor = unsafe { library .get::<*mut DynamicallyLinkedNodeInstance>(b"IRIDIS_NODE") .wrap_err(format!( "Failed to load symbol 'IRIDIS_NODE' from dylib {:?}", path_buf ))? .read() }; Ok::<_, eyre::Report>((library, constructor)) }) .await??; Ok(RuntimeNode::DynamicallyLinked(DynamicallyLinkedNode { _library: library, handle: (constructor)(inputs, outputs, queries, queryables, configuration) .await? .wrap_err(format!( "Failed to create dynamically linked node from dylib {:?}", path, ))?, })) } else { Err(eyre::eyre!( "Unsupported file extension '{:?}'. On this platform it must be '{}'", ext, std::env::consts::DLL_EXTENSION )) } } None => Err(eyre::eyre!("No file extension found for path {:?}", path)), } } } }
UrlSchemePlugin
An UrlSchemePlugin
takes a Url
as parameter and returns a RuntimeNode
. It also defines its target URL schemes. It can uses a FileExtPlugin
to load the file extension.
#![allow(unused)] fn main() { #[derive(UrlSchemePlugin)] pub struct DefaultUrlSchemePlugin {} #[url_scheme_plugin(runtime = "default_runtime")] impl UrlSchemePlugin for DefaultUrlSchemePlugin { async fn new() -> Result<Self> where Self: Sized, { Ok(DefaultUrlSchemePlugin {}) } fn target(&self) -> Vec<String> { vec!["file".to_string(), "builtin".to_string()] } #[allow(clippy::too_many_arguments)] async fn load( &self, url: Url, inputs: Inputs, outputs: Outputs, queries: Queries, queryables: Queryables, configuration: serde_yml::Value, file_ext: Arc<FileExtManager>, ) -> Result<iridis_runtime_core::prelude::RuntimeNode> { match url.scheme() { "file" => { let path = url .to_file_path() .map_err(|_| eyre::eyre!("Url '{}' cannot be made into a path buf", url))?; file_ext .load(path, inputs, outputs, queries, queryables, configuration) .await } "builtin" => Ok(RuntimeNode::StaticallyLinked( new_builtin( Builtin::from_string(url.path()) .wrap_err(format!("Invalid builtin name '{}'", url.path()))?, inputs, outputs, queries, queryables, configuration, ) .await?, )), _ => Err(eyre::eyre!( "Url scheme '{}' is not supported", url.scheme() )), } } } }