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