use async_trait::async_trait;
use ops::{
wet_put_arc, wet_require_ref, BatchOp, DryContext, Op, OpError, OpMetadata, OpResult,
WetContext,
};
use std::sync::Arc;
#[derive(Clone)]
struct FileSystemServiceImpl {
base_path: String,
}
impl FileSystemServiceImpl {
fn new(base_path: String) -> Self {
Self { base_path }
}
}
struct ValidateFolderPathOp;
struct ScanDirectoryOp;
#[async_trait]
impl Op<()> for ValidateFolderPathOp {
async fn perform(&self, _dry: &mut DryContext, wet: &mut WetContext) -> OpResult<()> {
println!("ValidateFolderPathOp: Checking for filesystem_service...");
if wet.contains("filesystem_service") {
println!("✓ filesystem_service reference found in wet context");
let filesystem_service: Arc<FileSystemServiceImpl> =
wet_require_ref!(wet, filesystem_service)?;
println!(
"✓ Successfully retrieved filesystem_service: {}",
filesystem_service.base_path
);
} else {
println!("✗ filesystem_service reference NOT found in wet context");
return Err(OpError::ExecutionFailed(
"filesystem_service not found".to_string(),
));
}
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("ValidateFolderPathOp")
.description("Validates folder path using filesystem service")
.build()
}
}
#[async_trait]
impl Op<Vec<String>> for ScanDirectoryOp {
async fn perform(&self, _dry: &mut DryContext, wet: &mut WetContext) -> OpResult<Vec<String>> {
println!("ScanDirectoryOp: Checking for filesystem_service...");
if wet.contains("filesystem_service") {
println!("✓ filesystem_service reference found in wet context");
let filesystem_service: Arc<FileSystemServiceImpl> =
wet_require_ref!(wet, filesystem_service)?;
println!(
"✓ Successfully retrieved filesystem_service: {}",
filesystem_service.base_path
);
let tracked_file_paths = vec![
"/path/to/file1.txt".to_string(),
"/path/to/file2.txt".to_string(),
];
println!("✓ Discovered {} files", tracked_file_paths.len());
Ok(tracked_file_paths)
} else {
println!("✗ filesystem_service reference NOT found in wet context");
Err(OpError::ExecutionFailed(
"filesystem_service not found".to_string(),
))
}
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("ScanDirectoryOp")
.description("Scans directory for files using filesystem service")
.build()
}
}
struct ScanDirectoryWrapperOp;
#[async_trait]
impl Op<()> for ScanDirectoryWrapperOp {
async fn perform(&self, dry: &mut DryContext, wet: &mut WetContext) -> OpResult<()> {
let scan_op = ScanDirectoryOp;
let tracked_files = scan_op.perform(dry, wet).await?;
println!(
"✓ ScanDirectoryWrapper found {} files:",
tracked_files.len()
);
for file in &tracked_files {
println!(" - {}", file);
}
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("ScanDirectoryWrapperOp")
.description("Wrapper that scans directory and handles results")
.build()
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Debug Filesystem Reference Issue with Dry/Wet Contexts ===");
let mut dry = DryContext::new();
let mut wet = WetContext::new();
let filesystem_service = Arc::new(FileSystemServiceImpl::new("/base/path".to_string()));
println!("1. Storing filesystem_service in wet context...");
println!(" - Using wet_put_arc! macro");
wet_put_arc!(wet, filesystem_service);
println!(" - wet_put_arc! call completed");
println!("2. Verifying storage...");
println!(" - Checking wet.contains(\"filesystem_service\")");
if wet.contains("filesystem_service") {
println!("✓ filesystem_service reference confirmed in wet context");
} else {
println!("✗ filesystem_service reference NOT found after storage!");
return Ok(());
}
println!("3. Testing direct access...");
let direct_access: Arc<FileSystemServiceImpl> = wet_require_ref!(wet, filesystem_service)?;
println!("✓ Direct access successful: {}", direct_access.base_path);
println!("4. Creating discovery batch...");
let discovery_batch = BatchOp::new(vec![
Arc::new(ValidateFolderPathOp) as Arc<dyn Op<()>>,
Arc::new(ScanDirectoryWrapperOp) as Arc<dyn Op<()>>,
]);
println!("5. Executing discovery batch...");
discovery_batch
.perform(&mut dry, &mut wet)
.await
.map_err(|e| OpError::ExecutionFailed(format!("Directory discovery failed: {}", e)))?;
println!("✓ Discovery batch completed successfully!");
println!("6. Testing individual op execution...");
let scan_op = ScanDirectoryOp;
let tracked_files = scan_op.perform(&mut dry, &mut wet).await?;
println!("✓ Found {} discovered files:", tracked_files.len());
for path in &tracked_files {
println!(" - {}", path);
}
println!("\n7. Op Metadata:");
println!(
"- {}: {}",
ValidateFolderPathOp.metadata().name,
ValidateFolderPathOp
.metadata()
.description
.unwrap_or("No description".to_string())
);
println!(
"- {}: {}",
ScanDirectoryOp.metadata().name,
ScanDirectoryOp
.metadata()
.description
.unwrap_or("No description".to_string())
);
println!("\n=== Test Completed Successfully ===");
Ok(())
}