codewhale_command_contract/
handler.rs1use crate::facets::{
8 CommandCostContext, CommandModePolicyContext, CommandModelContext, CommandSessionContext,
9 CommandSkillsContext, CommandSystemPromptContext, CommandWorkspaceContext,
10};
11
12#[derive(Clone, Copy)]
14pub enum CommandHandler<R> {
15 Pure(fn(Option<&str>) -> R),
16 Contextual(fn(CommandContexts<'_>, Option<&str>) -> R),
17}
18
19pub struct CommandContexts<'a> {
21 session: Option<&'a mut dyn CommandSessionContext>,
22 model: Option<&'a mut dyn CommandModelContext>,
23 cost: Option<&'a mut dyn CommandCostContext>,
24 mode_policy: Option<&'a mut dyn CommandModePolicyContext>,
25 system_prompt: Option<&'a mut dyn CommandSystemPromptContext>,
26 skills: Option<&'a mut dyn CommandSkillsContext>,
27 workspace: Option<&'a mut dyn CommandWorkspaceContext>,
28}
29
30pub struct ContextParts<'a> {
32 pub session: Option<&'a mut dyn CommandSessionContext>,
33 pub model: Option<&'a mut dyn CommandModelContext>,
34 pub cost: Option<&'a mut dyn CommandCostContext>,
35 pub mode_policy: Option<&'a mut dyn CommandModePolicyContext>,
36 pub system_prompt: Option<&'a mut dyn CommandSystemPromptContext>,
37 pub skills: Option<&'a mut dyn CommandSkillsContext>,
38 pub workspace: Option<&'a mut dyn CommandWorkspaceContext>,
39}
40
41impl<'a> CommandContexts<'a> {
42 pub fn empty() -> Self {
43 Self {
44 session: None,
45 model: None,
46 cost: None,
47 mode_policy: None,
48 system_prompt: None,
49 skills: None,
50 workspace: None,
51 }
52 }
53
54 pub fn into_parts(self) -> ContextParts<'a> {
55 ContextParts {
56 session: self.session,
57 model: self.model,
58 cost: self.cost,
59 mode_policy: self.mode_policy,
60 system_prompt: self.system_prompt,
61 skills: self.skills,
62 workspace: self.workspace,
63 }
64 }
65
66 pub fn with_session(mut self, value: &'a mut dyn CommandSessionContext) -> Self {
67 assert!(
68 self.session.replace(value).is_none(),
69 "session facet already set"
70 );
71 self
72 }
73
74 pub fn with_model(mut self, value: &'a mut dyn CommandModelContext) -> Self {
75 assert!(
76 self.model.replace(value).is_none(),
77 "model facet already set"
78 );
79 self
80 }
81
82 pub fn with_cost(mut self, value: &'a mut dyn CommandCostContext) -> Self {
83 assert!(self.cost.replace(value).is_none(), "cost facet already set");
84 self
85 }
86
87 pub fn with_mode_policy(mut self, value: &'a mut dyn CommandModePolicyContext) -> Self {
88 assert!(
89 self.mode_policy.replace(value).is_none(),
90 "mode-policy facet already set"
91 );
92 self
93 }
94
95 pub fn with_system_prompt(mut self, value: &'a mut dyn CommandSystemPromptContext) -> Self {
96 assert!(
97 self.system_prompt.replace(value).is_none(),
98 "system-prompt facet already set"
99 );
100 self
101 }
102
103 pub fn with_skills(mut self, value: &'a mut dyn CommandSkillsContext) -> Self {
104 assert!(
105 self.skills.replace(value).is_none(),
106 "skills facet already set"
107 );
108 self
109 }
110
111 pub fn with_workspace(mut self, value: &'a mut dyn CommandWorkspaceContext) -> Self {
112 assert!(
113 self.workspace.replace(value).is_none(),
114 "workspace facet already set"
115 );
116 self
117 }
118}
119
120impl Default for CommandContexts<'_> {
121 fn default() -> Self {
122 Self::empty()
123 }
124}