1#![feature(iterator_try_collect)]
2
3use anyhow::{Context, Result};
4use std::{
5 fs::{self, File},
6 path::PathBuf,
7};
8use zip::ZipArchive;
9
10use crate::meta::PluginMeta;
11
12pub mod loader;
13pub mod meta;
14
15#[derive(Debug)]
16pub struct LocatedPlugin {
17 pub meta: PluginMeta,
18 pub zip: ZipArchive<File>,
19 pub so: bool,
20 pub dll: bool,
21 pub dylib: bool,
22}
23
24pub fn locate_plugins(dir: PathBuf) -> Result<Vec<LocatedPlugin>> {
25 let mut plugins = Vec::new();
26
27 for entry in fs::read_dir(dir).context("failed reading directory")? {
28 let entry = entry.context("failed opening directory entry")?;
29 if entry.path().is_dir() {
30 continue;
31 }
32 if entry.path().extension().is_none_or(|ext| ext != "rstn") {
33 continue;
34 }
35
36 let mut zip = ZipArchive::new(File::open(entry.path()).context("failed opening file")?)
37 .context("failed reading zip")?;
38 let meta = meta::read(&mut zip)?;
39 let so = zip.by_name("plugin.so").is_ok();
40 let dll = zip.by_name("plugin.dll").is_ok();
41 let dylib = zip.by_name("plugin.dylib").is_ok();
42
43 plugins.push(LocatedPlugin {
44 meta,
45 zip,
46 so,
47 dll,
48 dylib,
49 });
50 }
51
52 Ok(plugins)
53}