tnn 0.1.3

A quality of life developer tool to interact with Telenor services
Documentation
use std::{path::PathBuf, str::FromStr};

use anyhow::Result;
use glob::glob;
use libloading::{Library, Symbol};

use crate::extension::Extension;

#[cfg(windows)]
const FILE_EXTENSION: &'static str = "dll";
#[cfg(linux)]
const FILE_EXTENSION: &'static str = "so";
#[cfg(target_os = "macos")]
const FILE_EXTENSION: &'static str = "dylib";

pub fn load_from_library(path: &str) -> Result<&'static Extension> {
	unsafe {
		let lib = Library::new(path)?;
		let manifest: Symbol<&'static Extension> = lib.get(b"MANIFEST")?;
		Ok(*manifest)
	}
}

pub fn load_from_directory(directory: &PathBuf) -> Result<Vec<&'static Extension>> {
	let pattern = directory.join(PathBuf::from_str(format!("*.{}", FILE_EXTENSION).as_str())?);

	let mut extensions: Vec<&'static Extension> = Vec::new();

	crate::debug!("Scanning {:?}", pattern);
	for result in glob(pattern.to_str().unwrap()).expect("") {
		match result {
			Err(err) => crate::critical!("{:?}", err),
			Ok(path) => {
				crate::debug!("Loading {:?}", path);
				match load_from_library(path.to_str().unwrap()) {
					Ok(extension) => {
						crate::debug!("Loaded [{}] {:?}", extension.name, path);
						extensions.push(extension);
					}
					Err(error) => {
						crate::warn!("Could not load extension from {:?}: {}", path, error);
					}
				};
			}
		}
	}

	Ok(extensions)
}