vx-tool-standard

Standard tool runtime interface and utilities for vx tool management.
English | 中文
Overview
vx-tool-standard provides a standardized interface and utilities for implementing tool runtimes in the vx ecosystem. It defines common patterns, traits, and helper functions that tool implementations can use to ensure consistency and interoperability.
Features
- Standard Tool Runtime Interface: Common traits for tool runtime operations
- Platform Abstraction: Cross-platform tool execution and management
- Configuration Management: Standardized tool configuration handling
- Error Handling: Consistent error types and handling patterns
- Utility Functions: Common operations for tool implementations
- Testing Utilities: Helper functions for testing tool implementations
Installation
Add this to your Cargo.toml:
[dependencies]
vx-tool-standard = "0.2.6"
Usage
Implementing a Tool Runtime
use vx_tool_standard::{ToolRuntime, VxResult, Platform};
use async_trait::async_trait;
struct MyToolRuntime {
name: String,
version: Option<String>,
}
#[async_trait]
impl ToolRuntime for MyToolRuntime {
async fn is_available(&self) -> VxResult<bool> {
Ok(which::which(&self.name).is_ok())
}
async fn get_version(&self) -> VxResult<Option<String>> {
Ok(self.version.clone())
}
async fn get_path(&self) -> VxResult<Option<PathBuf>> {
which::which(&self.name)
.map(Some)
.map_err(|e| e.into())
}
async fn execute(&self, args: &[String]) -> VxResult<i32> {
let status = std::process::Command::new(&self.name)
.args(args)
.status()?;
Ok(status.code().unwrap_or(1))
}
}
Using Standard Configurations
use vx_tool_standard::{StandardConfig, Platform};
let config = StandardConfig::builder()
.name("my-tool")
.version("1.0.0")
.description("My awesome tool")
.for_platforms(vec![Platform::Windows, Platform::Linux, Platform::MacOS])
.build();
println!("Tool: {} v{}", config.name(), config.version());
Platform-Specific Operations
use vx_tool_standard::Platform;
let current_platform = Platform::current();
match current_platform {
Platform::Windows => {
println!("Running on Windows");
}
Platform::Linux => {
println!("Running on Linux");
}
Platform::MacOS => {
println!("Running on macOS");
}
Platform::Unknown => {
println!("Unknown platform");
}
}
Error Handling
use vx_tool_standard::{VxResult, VxError};
fn tool_operation() -> VxResult<String> {
if some_condition {
Ok("Success".to_string())
} else {
Err(VxError::ToolNotFound("my-tool".to_string()))
}
}
match tool_operation() {
Ok(result) => println!("Success: {}", result),
Err(VxError::ToolNotFound(tool)) => {
eprintln!("Tool not found: {}", tool);
}
Err(e) => eprintln!("Error: {}", e),
}
Architecture
Core Traits
- ToolRuntime: Main interface for tool runtime operations
- Configurable: Interface for tools with configuration
- Executable: Interface for executable tools
- Versionable: Interface for tools with version information
Utility Types
- Platform: Platform detection and abstraction
- StandardConfig: Standard configuration structure
- VxResult: Standard result type with error handling
- VxError: Standard error types for tool operations
Advanced Usage
Custom Tool Configuration
use vx_tool_standard::{StandardConfig, Configurable};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct MyToolConfig {
#[serde(flatten)]
standard: StandardConfig,
custom_option: String,
debug_mode: bool,
}
impl Configurable for MyToolConfig {
type Config = Self;
fn config(&self) -> &Self::Config {
self
}
}
Testing Utilities
use vx_tool_standard::testing::{MockToolRuntime, TestEnvironment};
#[tokio::test]
async fn test_tool_runtime() {
let mut mock = MockToolRuntime::new("test-tool");
mock.expect_is_available().returning(|| Ok(true));
mock.expect_get_version().returning(|| Ok(Some("1.0.0".to_string())));
assert!(mock.is_available().await.unwrap());
assert_eq!(mock.get_version().await.unwrap(), Some("1.0.0".to_string()));
}
#[test]
fn test_with_environment() {
let env = TestEnvironment::new()
.with_tool("node", "18.17.0")
.with_tool("npm", "9.6.7");
env.run(|| {
assert!(which::which("node").is_ok());
assert!(which::which("npm").is_ok());
});
}
Integration with vx Ecosystem
Plugin Integration
use vx_tool_standard::{ToolRuntime, StandardConfig};
use vx_plugin::VxTool;
struct StandardTool {
config: StandardConfig,
runtime: Box<dyn ToolRuntime>,
}
impl VxTool for StandardTool {
fn name(&self) -> &str {
self.config.name()
}
fn description(&self) -> &str {
self.config.description()
}
}
Configuration Integration
use vx_tool_standard::StandardConfig;
use vx_config::VxConfig;
let vx_config = VxConfig::load()?;
let tool_config = StandardConfig::from_vx_config(&vx_config, "my-tool")?;
Examples
Check the examples/ directory for complete examples:
basic_tool.rs - Basic tool runtime implementation
configurable_tool.rs - Tool with custom configuration
platform_specific.rs - Platform-specific tool behavior
testing_example.rs - Testing tool implementations
Testing
cargo test
Run with logging:
RUST_LOG=vx_tool_standard=debug cargo test
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.