The libindigo library implements a dual-strategy pattern for INDIGO client connectivity, allowing users to choose between FFI-based (C library) or pure Rust implementations.
The client architecture uses the Strategy pattern to abstract the underlying implementation:
#[async_trait]
pub trait ClientStrategy: Send + Sync {
async fn connect(&mut self, url: &str) -> Result<()>;
async fn disconnect(&mut self) -> Result<()>;
async fn enumerate_properties(&mut self, device: Option<&str>) -> Result<()>;
async fn send_property(&mut self, property: Property) -> Result<()>;
// Optional monitoring support
#[cfg(feature = "monitoring")]
fn set_monitoring_config(&mut self, config: MonitoringConfig);
#[cfg(feature = "monitoring")]
fn subscribe_status(&self) -> Option<mpsc::UnboundedReceiver<ClientEvent>>;
}
Location: src/strategies/rs/
Features:
Components:
protocol.rs - XML protocol parser/serializerprotocol_json.rs - JSON protocol parser/serializerprotocol_negotiation.rs - Protocol version negotiationtransport.rs - TCP transport layerclient.rs - Client strategy implementationUsage:
let mut client = ClientBuilder::new()
.with_rs_strategy()
.build()?;
Location: src/strategies/ffi.rs, src/strategies/async_ffi.rs
Features:
Components:
ffi.rs - Synchronous FFI strategyasync_ffi.rs - Async FFI strategy with tokio integrationUsage:
let mut client = ClientBuilder::new()
.with_ffi_strategy()
.build()?;
Use Cargo features to select strategy:
# Default: client with async support
libindigo = "0.2"
# Pure Rust strategy (zero FFI dependencies)
libindigo = { version = "0.2", default-features = false, features = ["rs"] }
# FFI strategy
libindigo = { version = "0.2", default-features = false, features = ["ffi", "async"] }
Explicitly choose strategy in code:
// Pure Rust
let client = ClientBuilder::new()
.with_rs_strategy()
.build()?;
// FFI
let client = ClientBuilder::new()
.with_ffi_strategy()
.build()?;
| Feature | RS Strategy | FFI Strategy |
|---|---|---|
| XML Protocol | ✅ Complete | ✅ Complete |
| JSON Protocol | ✅ Complete | ❌ Not available |
| Protocol Negotiation | ✅ Complete | ✅ Complete |
| Async API | ✅ Native | ✅ Wrapped |
| Property Streaming | ✅ Complete | ✅ Complete |
| BLOB Support | ✅ Complete | ✅ Complete |
| Server Monitoring | ✅ Complete | 🚧 Partial (FFI types only) |
| Hardware Drivers | ❌ N/A | ✅ Complete |
Advantages:
Trade-offs:
Advantages:
Trade-offs:
Both strategies have comprehensive test coverage:
See tests/ directory for test implementations.
Both strategies support optional server monitoring through the monitoring feature flag.
The RS strategy has full monitoring support:
See Server Monitoring for details.
The FFI strategy provides monitoring types for C/C++ consumers:
Full monitoring implementation for FFI strategy is planned for a future release.