feat: Migrate SAL to Cargo workspace
Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled

- Migrate individual modules to independent crates
- Refactor dependencies for improved modularity
- Update build system and testing infrastructure
- Update documentation to reflect new structure
This commit is contained in:
Mahmoud-Emad
2025-06-24 12:39:18 +03:00
parent 8012a66250
commit e125bb6511
54 changed files with 1196 additions and 1582 deletions

View File

@@ -1,5 +1,5 @@
use std::fmt;
use std::error::Error;
use std::fmt;
/// Error types for RFS operations
#[derive(Debug)]
@@ -40,4 +40,4 @@ impl From<std::io::Error> for RfsError {
fn from(error: std::io::Error) -> Self {
RfsError::Other(format!("IO error: {}", error))
}
}
}

View File

@@ -1,14 +1,14 @@
mod builder;
mod cmd;
mod error;
mod mount;
mod pack;
mod builder;
mod types;
pub use builder::{PackBuilder, RfsBuilder};
pub use error::RfsError;
pub use builder::{RfsBuilder, PackBuilder};
pub use mount::{get_mount_info, list_mounts, unmount, unmount_all};
pub use pack::{list_contents, pack_directory, unpack, verify};
pub use types::{Mount, MountType, StoreSpec};
pub use mount::{list_mounts, unmount_all, unmount, get_mount_info};
pub use pack::{pack_directory, unpack, list_contents, verify};
// Re-export the execute_rfs_command function for use in other modules

View File

@@ -1,8 +1,4 @@
use super::{
error::RfsError,
cmd::execute_rfs_command,
types::Mount,
};
use super::{cmd::execute_rfs_command, error::RfsError, types::Mount};
/// List all mounted filesystems
///
@@ -12,38 +8,40 @@ use super::{
pub fn list_mounts() -> Result<Vec<Mount>, RfsError> {
// Execute the list command
let result = execute_rfs_command(&["list", "--json"])?;
// Parse the JSON output
match serde_json::from_str::<serde_json::Value>(&result.stdout) {
Ok(json) => {
if let serde_json::Value::Array(mounts_json) = json {
let mut mounts = Vec::new();
for mount_json in mounts_json {
// Extract mount ID
let id = match mount_json.get("id").and_then(|v| v.as_str()) {
Some(id) => id.to_string(),
None => return Err(RfsError::ListFailed("Missing mount ID".to_string())),
};
// Extract source
let source = match mount_json.get("source").and_then(|v| v.as_str()) {
Some(source) => source.to_string(),
None => return Err(RfsError::ListFailed("Missing source".to_string())),
};
// Extract target
let target = match mount_json.get("target").and_then(|v| v.as_str()) {
Some(target) => target.to_string(),
None => return Err(RfsError::ListFailed("Missing target".to_string())),
};
// Extract filesystem type
let fs_type = match mount_json.get("type").and_then(|v| v.as_str()) {
Some(fs_type) => fs_type.to_string(),
None => return Err(RfsError::ListFailed("Missing filesystem type".to_string())),
None => {
return Err(RfsError::ListFailed("Missing filesystem type".to_string()))
}
};
// Extract options
let options = match mount_json.get("options").and_then(|v| v.as_array()) {
Some(options_array) => {
@@ -54,10 +52,10 @@ pub fn list_mounts() -> Result<Vec<Mount>, RfsError> {
}
}
options_vec
},
}
None => Vec::new(), // Empty vector if no options found
};
// Create Mount struct and add to vector
mounts.push(Mount {
id,
@@ -67,15 +65,16 @@ pub fn list_mounts() -> Result<Vec<Mount>, RfsError> {
options,
});
}
Ok(mounts)
} else {
Err(RfsError::ListFailed("Expected JSON array".to_string()))
}
},
Err(e) => {
Err(RfsError::ListFailed(format!("Failed to parse mount list JSON: {}", e)))
}
Err(e) => Err(RfsError::ListFailed(format!(
"Failed to parse mount list JSON: {}",
e
))),
}
}
@@ -91,12 +90,15 @@ pub fn list_mounts() -> Result<Vec<Mount>, RfsError> {
pub fn unmount(target: &str) -> Result<(), RfsError> {
// Execute the unmount command
let result = execute_rfs_command(&["unmount", target])?;
// Check for errors
if !result.success {
return Err(RfsError::UnmountFailed(format!("Failed to unmount {}: {}", target, result.stderr)));
return Err(RfsError::UnmountFailed(format!(
"Failed to unmount {}: {}",
target, result.stderr
)));
}
Ok(())
}
@@ -108,12 +110,15 @@ pub fn unmount(target: &str) -> Result<(), RfsError> {
pub fn unmount_all() -> Result<(), RfsError> {
// Execute the unmount all command
let result = execute_rfs_command(&["unmount", "--all"])?;
// Check for errors
if !result.success {
return Err(RfsError::UnmountFailed(format!("Failed to unmount all filesystems: {}", result.stderr)));
return Err(RfsError::UnmountFailed(format!(
"Failed to unmount all filesystems: {}",
result.stderr
)));
}
Ok(())
}
@@ -129,14 +134,14 @@ pub fn unmount_all() -> Result<(), RfsError> {
pub fn get_mount_info(target: &str) -> Result<Mount, RfsError> {
// Get all mounts
let mounts = list_mounts()?;
// Find the mount with the specified target
for mount in mounts {
if mount.target == target {
return Ok(mount);
}
}
// Mount not found
Err(RfsError::Other(format!("No mount found at {}", target)))
}
}

View File

@@ -1,9 +1,4 @@
use super::{
error::RfsError,
cmd::execute_rfs_command,
types::StoreSpec,
builder::PackBuilder,
};
use super::{builder::PackBuilder, cmd::execute_rfs_command, error::RfsError, types::StoreSpec};
/// Pack a directory into a filesystem layer
///
@@ -16,15 +11,19 @@ use super::{
/// # Returns
///
/// * `Result<(), RfsError>` - Success or error
pub fn pack_directory(directory: &str, output: &str, store_specs: &[StoreSpec]) -> Result<(), RfsError> {
pub fn pack_directory(
directory: &str,
output: &str,
store_specs: &[StoreSpec],
) -> Result<(), RfsError> {
// Create a new pack builder
let mut builder = PackBuilder::new(directory, output);
// Add store specs
for spec in store_specs {
builder = builder.with_store_spec(spec.clone());
}
// Pack the directory
builder.pack()
}
@@ -42,12 +41,15 @@ pub fn pack_directory(directory: &str, output: &str, store_specs: &[StoreSpec])
pub fn unpack(input: &str, directory: &str) -> Result<(), RfsError> {
// Execute the unpack command
let result = execute_rfs_command(&["unpack", "-m", input, directory])?;
// Check for errors
if !result.success {
return Err(RfsError::Other(format!("Failed to unpack {}: {}", input, result.stderr)));
return Err(RfsError::Other(format!(
"Failed to unpack {}: {}",
input, result.stderr
)));
}
Ok(())
}
@@ -63,12 +65,15 @@ pub fn unpack(input: &str, directory: &str) -> Result<(), RfsError> {
pub fn list_contents(input: &str) -> Result<String, RfsError> {
// Execute the list command
let result = execute_rfs_command(&["list", "-m", input])?;
// Check for errors
if !result.success {
return Err(RfsError::Other(format!("Failed to list contents of {}: {}", input, result.stderr)));
return Err(RfsError::Other(format!(
"Failed to list contents of {}: {}",
input, result.stderr
)));
}
Ok(result.stdout)
}
@@ -84,7 +89,7 @@ pub fn list_contents(input: &str) -> Result<String, RfsError> {
pub fn verify(input: &str) -> Result<bool, RfsError> {
// Execute the verify command
let result = execute_rfs_command(&["verify", "-m", input])?;
// Check for errors
if !result.success {
// If the command failed but returned a specific error about verification,
@@ -92,9 +97,12 @@ pub fn verify(input: &str) -> Result<bool, RfsError> {
if result.stderr.contains("verification failed") {
return Ok(false);
}
return Err(RfsError::Other(format!("Failed to verify {}: {}", input, result.stderr)));
return Err(RfsError::Other(format!(
"Failed to verify {}: {}",
input, result.stderr
)));
}
Ok(true)
}
}

View File

@@ -41,7 +41,7 @@ impl MountType {
MountType::Custom(s) => s.clone(),
}
}
/// Create a MountType from a string
pub fn from_string(s: &str) -> Self {
match s.to_lowercase().as_str() {
@@ -102,16 +102,17 @@ impl StoreSpec {
/// * `String` - String representation of the store specification
pub fn to_string(&self) -> String {
let mut result = self.spec_type.clone();
if !self.options.is_empty() {
result.push_str(":");
let options: Vec<String> = self.options
let options: Vec<String> = self
.options
.iter()
.map(|(k, v)| format!("{}={}", k, v))
.collect();
result.push_str(&options.join(","));
}
result
}
}
}