1use crate::prelude::*;
2use anyhow::Result;
3
4#[derive(Clone, Copy)]
5pub struct SkillEntry {
6 pub model_id: &'static [u8],
7 pub init: fn(&Environment) -> Result<Skill>,
8}
9
10#[derive(Clone, Copy)]
11pub struct NamedSkillEntry {
12 pub key: &'static str,
13 pub entry: SkillEntry,
14}
15
16pub trait Labeler: Send + Sync + 'static {
17 fn label_features(&self, input: &[Token]) -> Vec<Vec<Feature>>;
18}
19
20pub trait Corpus: Send + Sync + 'static {
21 fn training_data(&self) -> Vec<Vec<Token>>;
22 fn weight(&self) -> f64 {
23 1.0
24 }
25}
26
27pub trait Suggestions: Send + Sync + 'static {
28 fn suggestions(&self, seed: u64, args: &[Token], streams: &[InputStream]) -> Vec<String>;
29}
30
31pub trait Preprocessor: Send + Sync + 'static {
32 fn preprocess(&self, input: Vec<Token>) -> Vec<Token>;
33}
34
35pub trait Translator: Send + Sync + 'static {
36 fn generate_command(&self, args: &[Token], _streams: &[InputStream]) -> Option<CommandArgs>;
37}
38
39pub trait Command: Send + Sync + 'static {
40 fn run(
41 &self,
42 args: CommandArgs,
43 _streams: &mut [InputStream],
44 _user: &UserContext,
45 ) -> Result<Output, CommandError>;
46 fn priority(&self) -> i32 {
47 0
48 }
49}
50
51#[derive(Default)]
52pub struct Skill {
53 pub corpora: Vec<Box<dyn Corpus>>,
54 pub suggestions: Vec<Box<dyn Suggestions>>,
55 pub labelers: Vec<Box<dyn Labeler>>,
56 pub preprocessors: Vec<Box<dyn Preprocessor>>,
57 pub translators: Vec<Box<dyn Translator>>,
58 pub command: Option<Box<dyn Command>>,
59}
60
61impl Skill {
62 pub fn builder() -> SkillBuilder {
63 Default::default()
64 }
65}
66
67#[derive(Default)]
68pub struct SkillBuilder {
69 skill: Skill,
70}
71
72impl SkillBuilder {
73 pub fn add_corpus<T: Corpus>(mut self, item: T) -> Self {
74 self.skill.corpora.push(Box::new(item));
75 self
76 }
77
78 pub fn add_suggestions<T: Suggestions>(mut self, item: T) -> Self {
79 self.skill.suggestions.push(Box::new(item));
80 self
81 }
82
83 pub fn add_labeler<T: Labeler>(mut self, item: T) -> Self {
84 self.skill.labelers.push(Box::new(item));
85 self
86 }
87
88 pub fn add_translator<T: Translator>(mut self, item: T) -> Self {
89 self.skill.translators.push(Box::new(item));
90 self
91 }
92
93 pub fn add_preprocessor<T: Preprocessor>(mut self, item: T) -> Self {
94 self.skill.preprocessors.push(Box::new(item));
95 self
96 }
97
98 pub fn set_command<T: Command>(mut self, item: T) -> Self {
99 self.skill.command = Some(Box::new(item));
100 self
101 }
102
103 pub fn build(self) -> Result<Skill> {
104 Ok(self.skill)
105 }
106}