feat: Migrate SAL to Cargo workspace
- 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:
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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)))
|
||||
}
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user