crabtalk_runtime/skill/
handler.rs1use crate::skill::{SkillRegistry, loader};
4use anyhow::Result;
5use std::path::PathBuf;
6use tokio::sync::Mutex;
7
8pub struct SkillHandler {
10 pub registry: Mutex<SkillRegistry>,
12 pub skill_dirs: Vec<PathBuf>,
14}
15
16impl Default for SkillHandler {
17 fn default() -> Self {
18 Self {
19 registry: Mutex::new(SkillRegistry::new()),
20 skill_dirs: Vec::new(),
21 }
22 }
23}
24
25impl SkillHandler {
26 pub fn load(skill_dirs: Vec<PathBuf>) -> Result<Self> {
29 let mut registry = SkillRegistry::new();
30 for dir in &skill_dirs {
31 if !dir.exists() {
32 continue;
33 }
34 match loader::load_skills_dir(dir) {
35 Ok(r) => {
36 let count = r.len();
37 for skill in r.skills() {
38 if registry.contains(&skill.name) {
39 tracing::warn!(
40 "skill '{}' from {} conflicts with already-loaded skill, skipping",
41 skill.name,
42 dir.display()
43 );
44 } else {
45 registry.add(skill.clone());
46 }
47 }
48 tracing::info!("loaded {count} skill(s) from {}", dir.display());
49 }
50 Err(e) => {
51 tracing::warn!("could not load skills from {}: {e}", dir.display());
52 }
53 }
54 }
55 tracing::info!("total {} skill(s) loaded", registry.len());
56 Ok(Self {
57 registry: Mutex::new(registry),
58 skill_dirs,
59 })
60 }
61}