- Core crate: Minimal shell-out implementation - Advanced crate: Pluggable backends and enhanced features - Main crate: Re-exports core + optional advanced features - Feature flags: Users choose complexity level - Examples: Working demonstrations of both approaches - Documentation: Clear README explaining the structure Implements the refined two-crate approach with workspace + feature flags.
105 lines
4.5 KiB
Rust
105 lines
4.5 KiB
Rust
//! Example demonstrating backend selection and switching.
|
|
|
|
use apt_dnf_bridge::{
|
|
BackendConfig, Package, TransactionV2, PackageDatabaseV2,
|
|
};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
println!("APT-DNF Bridge - Backend Selection Example");
|
|
println!("======================================");
|
|
|
|
// 1. Auto-detect the best available backend
|
|
println!("1. Auto-detecting best backend...");
|
|
let tx = TransactionV2::new().await?;
|
|
let (backend_name, backend_version) = tx.backend_info();
|
|
println!(" Selected backend: {} v{}", backend_name, backend_version);
|
|
|
|
// 2. Create a transaction with shell backend explicitly
|
|
println!("\n2. Creating transaction with shell backend...");
|
|
let config = BackendConfig {
|
|
enable_logging: true,
|
|
use_cache: true,
|
|
max_cache_size: 1000,
|
|
command_timeout: Some(300),
|
|
};
|
|
let shell_tx = TransactionV2::with_shell_backend(config).await?;
|
|
let (shell_name, shell_version) = shell_tx.backend_info();
|
|
println!(" Shell backend: {} v{}", shell_name, shell_version);
|
|
|
|
// 3. Create a package database with mock backend for testing
|
|
println!("\n3. Creating package database with mock backend...");
|
|
let mock_config = BackendConfig {
|
|
enable_logging: true,
|
|
use_cache: true,
|
|
max_cache_size: 100,
|
|
command_timeout: Some(30),
|
|
};
|
|
let mut mock_db = PackageDatabaseV2::with_mock_backend(mock_config).await?;
|
|
let (_mock_name, mock_version) = mock_db.backend_info();
|
|
println!(" Mock backend: v{}", mock_version);
|
|
|
|
// 4. Demonstrate backend capabilities
|
|
println!("\n4. Testing backend capabilities...");
|
|
|
|
// Test mock backend
|
|
println!(" Testing mock backend:");
|
|
let packages = mock_db.find_packages("vim").await?;
|
|
println!(" Found {} packages matching 'vim'", packages.len());
|
|
|
|
if let Some(pkg_info) = mock_db.get_package_info("vim").await? {
|
|
println!(" Package info: {} {}", pkg_info.name, pkg_info.version);
|
|
}
|
|
|
|
// Test shell backend (if available)
|
|
println!(" Testing shell backend:");
|
|
let mut shell_db = PackageDatabaseV2::with_shell_backend(BackendConfig::default()).await?;
|
|
let shell_packages = shell_db.find_packages("vim").await?;
|
|
println!(" Found {} packages matching 'vim'", shell_packages.len());
|
|
|
|
// 5. Demonstrate transaction with different backends
|
|
println!("\n5. Testing transactions with different backends...");
|
|
|
|
let vim = Package::new("vim", "2:8.1.2269-1ubuntu5.14", "amd64");
|
|
|
|
// Mock transaction
|
|
let mut mock_tx = TransactionV2::with_mock_backend(BackendConfig::default()).await?;
|
|
mock_tx.add_install(vim.clone()).await?;
|
|
println!(" Mock transaction: {} operations", mock_tx.len());
|
|
|
|
let resolution = mock_tx.resolve().await?;
|
|
println!(" Mock resolution: resolvable={}, summary='{}'",
|
|
resolution.resolvable, resolution.summary);
|
|
|
|
// Shell transaction (if available)
|
|
let mut shell_tx = TransactionV2::with_shell_backend(BackendConfig::default()).await?;
|
|
shell_tx.add_install(vim).await?;
|
|
println!(" Shell transaction: {} operations", shell_tx.len());
|
|
|
|
let shell_resolution = shell_tx.resolve().await?;
|
|
println!(" Shell resolution: resolvable={}, summary='{}'",
|
|
shell_resolution.resolvable, shell_resolution.summary);
|
|
|
|
// 6. Show backend statistics
|
|
println!("\n6. Backend statistics:");
|
|
let mock_stats = mock_db.get_backend_stats().await?;
|
|
println!(" Mock backend stats:");
|
|
println!(" Commands executed: {}", mock_stats.commands_executed);
|
|
println!(" Packages queried: {}", mock_stats.packages_queried);
|
|
println!(" Cache hit rate: {:.2}%", mock_stats.cache_hit_rate * 100.0);
|
|
|
|
let shell_stats = shell_db.get_backend_stats().await?;
|
|
println!(" Shell backend stats:");
|
|
println!(" Commands executed: {}", shell_stats.commands_executed);
|
|
println!(" Packages queried: {}", shell_stats.packages_queried);
|
|
println!(" Cache hit rate: {:.2}%", shell_stats.cache_hit_rate * 100.0);
|
|
|
|
println!("\n✅ Backend selection example completed successfully!");
|
|
println!("\n💡 Key benefits of pluggable backends:");
|
|
println!(" • Start with simple shell backend (reliable)");
|
|
println!(" • Switch to libapt backend when available (more powerful)");
|
|
println!(" • Use mock backend for testing (fast, predictable)");
|
|
println!(" • Same API works with all backends");
|
|
|
|
Ok(())
|
|
}
|