monoloop_loop/transaction/
resolved_tools.rs1use super::host_tools::RegisteredTool;
4use super::tool_handler::ToolHandler;
5use monoloop_contracts::{ToolId, ToolName, ToolSpec};
6use std::collections::HashMap;
7use std::sync::Arc;
8
9#[derive(Clone)]
11pub struct ResolvedTool {
12 pub spec: ToolSpec,
14 pub handler: Arc<dyn ToolHandler>,
16}
17
18impl std::fmt::Debug for ResolvedTool {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 f.debug_struct("ResolvedTool")
21 .field("spec", &self.spec)
22 .field("handler", &"<dyn ToolHandler>")
23 .finish()
24 }
25}
26
27#[derive(Clone, Debug, Default)]
29pub struct ResolvedToolSet {
30 by_id: HashMap<ToolId, ResolvedTool>,
31 by_name: HashMap<ToolName, ToolId>,
32 ordered: Vec<ToolId>,
33}
34
35impl ResolvedToolSet {
36 pub fn empty() -> Self {
38 Self::default()
39 }
40
41 pub fn from_registered(tools: Vec<RegisteredTool>) -> Self {
43 let mut by_id = HashMap::new();
44 let mut by_name = HashMap::new();
45 let mut ordered = Vec::with_capacity(tools.len());
46 for tool in tools {
47 by_name.insert(tool.spec.name.clone(), tool.spec.id.clone());
48 ordered.push(tool.spec.id.clone());
49 by_id.insert(
50 tool.spec.id.clone(),
51 ResolvedTool {
52 spec: tool.spec,
53 handler: tool.handler,
54 },
55 );
56 }
57 Self {
58 by_id,
59 by_name,
60 ordered,
61 }
62 }
63
64 pub fn is_empty(&self) -> bool {
66 self.by_id.is_empty()
67 }
68
69 pub fn len(&self) -> usize {
71 self.by_id.len()
72 }
73
74 pub fn specs(&self) -> Vec<&ToolSpec> {
76 self.ordered
77 .iter()
78 .filter_map(|id| self.by_id.get(id).map(|t| &t.spec))
79 .collect()
80 }
81
82 pub fn tools(&self) -> Vec<&ResolvedTool> {
84 self.ordered
85 .iter()
86 .filter_map(|id| self.by_id.get(id))
87 .collect()
88 }
89
90 pub fn get(&self, id: &ToolId) -> Option<&ResolvedTool> {
92 self.by_id.get(id)
93 }
94
95 pub fn get_by_name(&self, name: &ToolName) -> Option<&ResolvedTool> {
97 self.by_name.get(name).and_then(|id| self.by_id.get(id))
98 }
99
100 pub fn contains_name(&self, name: &ToolName) -> bool {
102 self.by_name.contains_key(name)
103 }
104}