fidius-host::package Rust¶
Host-side package integration: manifest loading, discovery, and building.
Functions¶
fidius-host::package::load_package_manifest¶
pub
fn load_package_manifest < M : DeserializeOwned > (dir : & Path ,) -> Result < PackageManifest < M > , PackageError >
Load and validate a package manifest against a host-defined schema.
This is the primary entry point for host applications working with packages.
The type parameter M is the host's metadata schema — if the manifest's
[metadata] section doesn't deserialize into M, this returns an error.
Examples:
#[derive(Deserialize)]
struct MySchema {
category: String,
min_host_version: String,
}
let manifest = load_package_manifest::<MySchema>(Path::new("./packages/blur/"))?;
assert_eq!(manifest.metadata.category, "image-processing");
Source
fidius-host::package::discover_packages¶
pub
Discover packages in a directory.
Scans dir for subdirectories containing a package.toml file.
Returns the paths to each package directory found.
Source
pub fn discover_packages(dir: &Path) -> Result<Vec<PathBuf>, PackageError> {
let mut packages = Vec::new();
if !dir.is_dir() {
return Ok(packages);
}
let entries = std::fs::read_dir(dir).map_err(PackageError::Io)?;
for entry in entries {
let entry = entry.map_err(PackageError::Io)?;
let path = entry.path();
if path.is_dir() && path.join("package.toml").exists() {
packages.push(path);
}
}
packages.sort();
Ok(packages)
}
fidius-host::package::verify_package¶
pub
Verify a source package's signature against trusted public keys.
Recomputes the package digest from files on disk and verifies the
package.sig signature against the provided trusted keys.
Raises:
| Exception | Description |
|---|---|
PackageError::SignatureNotFound |
— if package.sig doesn't exist |
PackageError::SignatureInvalid |
— if no trusted key verifies the signature |
Source
pub fn verify_package(dir: &Path, trusted_keys: &[VerifyingKey]) -> Result<(), PackageError> {
let sig_path = dir.join("package.sig");
if !sig_path.exists() {
return Err(PackageError::SignatureNotFound {
path: dir.display().to_string(),
});
}
let sig_bytes: [u8; 64] =
std::fs::read(&sig_path)?
.try_into()
.map_err(|_| PackageError::SignatureInvalid {
path: dir.display().to_string(),
})?;
let signature = Signature::from_bytes(&sig_bytes);
let digest = fidius_core::package::package_digest(dir)?;
for key in trusted_keys {
if key.verify(&digest, &signature).is_ok() {
return Ok(());
}
}
Err(PackageError::SignatureInvalid {
path: dir.display().to_string(),
})
}
fidius-host::package::unpack_fid¶
pub
Extract a .fid archive and validate its contents.
Delegates to [fidius_core::package::unpack_package] and emits a
tracing::warn! if the unpacked package has no package.sig.
Examples:
let pkg_dir = unpack_fid(Path::new("blur-filter-1.0.0.fid"), Path::new("./plugins/"))?;
let manifest = load_package_manifest::<MySchema>(&pkg_dir)?;
Source
pub fn unpack_fid(archive: &Path, dest: &Path) -> Result<PathBuf, PackageError> {
let pkg_dir = fidius_core::package::unpack_package(archive, dest)?;
if !pkg_dir.join("package.sig").exists() {
#[cfg(feature = "tracing")]
tracing::warn!(
package = %pkg_dir.display(),
"unpacked package is unsigned (no package.sig found)"
);
}
Ok(pkg_dir)
}
fidius-host::package::build_package¶
pub
Build a package by running cargo build inside the package directory.
Returns the path to the compiled cdylib on success.
Source
pub fn build_package(dir: &Path, release: bool) -> Result<PathBuf, PackageError> {
let cargo_toml = dir.join("Cargo.toml");
if !cargo_toml.exists() {
return Err(PackageError::BuildFailed(format!(
"Cargo.toml not found in {}",
dir.display()
)));
}
let mut cmd = std::process::Command::new("cargo");
cmd.arg("build").arg("--manifest-path").arg(&cargo_toml);
if release {
cmd.arg("--release");
}
let output = cmd.output().map_err(PackageError::Io)?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
return Err(PackageError::BuildFailed(stderr.to_string()));
}
let profile = if release { "release" } else { "debug" };
let target_dir = dir.join("target").join(profile);
// Find the cdylib in the target directory
let dylib_ext = if cfg!(target_os = "macos") {
"dylib"
} else if cfg!(target_os = "windows") {
"dll"
} else {
"so"
};
// Look for any file with the right extension
if let Ok(entries) = std::fs::read_dir(&target_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) == Some(dylib_ext) {
return Ok(path);
}
}
}
Err(PackageError::BuildFailed(format!(
"build succeeded but no .{} file found in {}",
dylib_ext,
target_dir.display()
)))
}