use std::path::PathBuf;
use skm_core::SkillName;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum DisclosureLevel {
Catalog,
Activated,
Referenced,
}
impl DisclosureLevel {
pub fn level(&self) -> u8 {
match self {
Self::Catalog => 0,
Self::Activated => 1,
Self::Referenced => 2,
}
}
pub fn has_instructions(&self) -> bool {
matches!(self, Self::Activated | Self::Referenced)
}
}
impl Default for DisclosureLevel {
fn default() -> Self {
Self::Catalog
}
}
#[derive(Debug, Clone)]
pub struct LoadedSkill {
pub name: SkillName,
pub level: DisclosureLevel,
pub tokens_used: usize,
pub loaded_files: Vec<PathBuf>,
}
impl LoadedSkill {
pub fn new(name: SkillName, level: DisclosureLevel, tokens_used: usize) -> Self {
Self {
name,
level,
tokens_used,
loaded_files: Vec::new(),
}
}
pub fn add_file(&mut self, path: PathBuf, additional_tokens: usize) {
self.loaded_files.push(path);
self.tokens_used += additional_tokens;
self.level = DisclosureLevel::Referenced;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_disclosure_level_ordering() {
assert_eq!(DisclosureLevel::Catalog.level(), 0);
assert_eq!(DisclosureLevel::Activated.level(), 1);
assert_eq!(DisclosureLevel::Referenced.level(), 2);
}
#[test]
fn test_has_instructions() {
assert!(!DisclosureLevel::Catalog.has_instructions());
assert!(DisclosureLevel::Activated.has_instructions());
assert!(DisclosureLevel::Referenced.has_instructions());
}
#[test]
fn test_loaded_skill() {
let name = SkillName::new("test").unwrap();
let mut skill = LoadedSkill::new(name, DisclosureLevel::Activated, 1000);
assert_eq!(skill.tokens_used, 1000);
assert!(skill.loaded_files.is_empty());
skill.add_file(PathBuf::from("references/data.md"), 500);
assert_eq!(skill.tokens_used, 1500);
assert_eq!(skill.level, DisclosureLevel::Referenced);
assert_eq!(skill.loaded_files.len(), 1);
}
}