feat(phase4): complete zclaw-skills, zclaw-hands, zclaw-channels, zclaw-protocols 模块实现
This commit is contained in:
131
crates/zclaw-hands/src/registry.rs
Normal file
131
crates/zclaw-hands/src/registry.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
//! Hand and Trigger registries
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use zclaw_types::Result;
|
||||
|
||||
use super::{Hand, HandConfig, HandContext, HandResult, Trigger, TriggerConfig};
|
||||
|
||||
/// Hand registry
|
||||
pub struct HandRegistry {
|
||||
hands: RwLock<HashMap<String, Arc<dyn Hand>>>,
|
||||
configs: RwLock<HashMap<String, HandConfig>>,
|
||||
}
|
||||
|
||||
impl HandRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
hands: RwLock::new(HashMap::new()),
|
||||
configs: RwLock::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a hand
|
||||
pub async fn register(&self, hand: Arc<dyn Hand>) {
|
||||
let config = hand.config().clone();
|
||||
let mut hands = self.hands.write().await;
|
||||
let mut configs = self.configs.write().await;
|
||||
|
||||
hands.insert(config.id.clone(), hand);
|
||||
configs.insert(config.id.clone(), config);
|
||||
}
|
||||
|
||||
/// Get a hand by ID
|
||||
pub async fn get(&self, id: &str) -> Option<Arc<dyn Hand>> {
|
||||
let hands = self.hands.read().await;
|
||||
hands.get(id).cloned()
|
||||
}
|
||||
|
||||
/// Get hand configuration
|
||||
pub async fn get_config(&self, id: &str) -> Option<HandConfig> {
|
||||
let configs = self.configs.read().await;
|
||||
configs.get(id).cloned()
|
||||
}
|
||||
|
||||
/// List all hands
|
||||
pub async fn list(&self) -> Vec<HandConfig> {
|
||||
let configs = self.configs.read().await;
|
||||
configs.values().cloned().collect()
|
||||
}
|
||||
|
||||
/// Execute a hand
|
||||
pub async fn execute(
|
||||
&self,
|
||||
id: &str,
|
||||
context: &HandContext,
|
||||
input: serde_json::Value,
|
||||
) -> Result<HandResult> {
|
||||
let hand = self.get(id).await
|
||||
.ok_or_else(|| zclaw_types::ZclawError::NotFound(format!("Hand not found: {}", id)))?;
|
||||
|
||||
hand.execute(context, input).await
|
||||
}
|
||||
|
||||
/// Remove a hand
|
||||
pub async fn remove(&self, id: &str) {
|
||||
let mut hands = self.hands.write().await;
|
||||
let mut configs = self.configs.write().await;
|
||||
|
||||
hands.remove(id);
|
||||
configs.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for HandRegistry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Trigger registry
|
||||
pub struct TriggerRegistry {
|
||||
triggers: RwLock<HashMap<String, Arc<dyn Trigger>>>,
|
||||
configs: RwLock<HashMap<String, TriggerConfig>>,
|
||||
}
|
||||
|
||||
impl TriggerRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
triggers: RwLock::new(HashMap::new()),
|
||||
configs: RwLock::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a trigger
|
||||
pub async fn register(&self, trigger: Arc<dyn Trigger>) {
|
||||
let config = trigger.config().clone();
|
||||
let mut triggers = self.triggers.write().await;
|
||||
let mut configs = self.configs.write().await;
|
||||
|
||||
triggers.insert(config.id.clone(), trigger);
|
||||
configs.insert(config.id.clone(), config);
|
||||
}
|
||||
|
||||
/// Get a trigger by ID
|
||||
pub async fn get(&self, id: &str) -> Option<Arc<dyn Trigger>> {
|
||||
let triggers = self.triggers.read().await;
|
||||
triggers.get(id).cloned()
|
||||
}
|
||||
|
||||
/// List all triggers
|
||||
pub async fn list(&self) -> Vec<TriggerConfig> {
|
||||
let configs = self.configs.read().await;
|
||||
configs.values().cloned().collect()
|
||||
}
|
||||
|
||||
/// Remove a trigger
|
||||
pub async fn remove(&self, id: &str) {
|
||||
let mut triggers = self.triggers.write().await;
|
||||
let mut configs = self.configs.write().await;
|
||||
|
||||
triggers.remove(id);
|
||||
configs.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TriggerRegistry {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user