zen_engine/workspace/graph/
function.rs1use std::hash::{Hash, Hasher};
2use std::sync::Arc;
3
4use zen_expression::variable::VariableType;
5
6use crate::workspace::db::Db;
7use crate::workspace::graph::ts_type::TsTypeParser;
8
9pub type FunctionTypeResolver = dyn Fn(&str, &VariableType) -> Option<String>;
10
11pub(crate) type FunctionKey = (u64, u64);
12
13#[derive(Debug, Clone)]
14pub struct FunctionResolutionRequest {
15 pub source: Arc<str>,
16 pub input: VariableType,
17}
18
19#[derive(Debug, Clone)]
20pub(crate) enum ResolvedFunction {
21 Type(VariableType),
22 Unresolved,
23}
24
25pub(crate) enum FunctionTypeOutcome {
26 Typed(VariableType),
27 Unresolved,
28 Unknown,
29}
30
31impl Db {
32 pub(crate) fn function_output_type(
33 &self,
34 source: &Arc<str>,
35 input: &VariableType,
36 ) -> FunctionTypeOutcome {
37 let key = Self::function_key(source, input);
38 let outcome = self.function_outcome(key, source, input);
39 self.graph_fn_record(key, self.function_state(key));
40 outcome
41 }
42
43 fn function_outcome(
44 &self,
45 key: FunctionKey,
46 source: &Arc<str>,
47 input: &VariableType,
48 ) -> FunctionTypeOutcome {
49 if let Some(entry) = self.function_types().borrow().get(&key) {
50 return match entry {
51 ResolvedFunction::Type(t) => FunctionTypeOutcome::Typed(t.shallow_clone()),
52 ResolvedFunction::Unresolved => FunctionTypeOutcome::Unresolved,
53 };
54 }
55
56 if let Some(resolver) = self.function_resolver().borrow().as_ref() {
57 let entry = match resolver(source.as_ref(), input) {
58 Some(ts) => match TsTypeParser::variable_type(&ts) {
59 Some(resolved) => ResolvedFunction::Type(resolved),
60 None => ResolvedFunction::Unresolved,
61 },
62 None => ResolvedFunction::Unresolved,
63 };
64 self.function_types()
65 .borrow_mut()
66 .insert(key, entry.clone());
67 return match entry {
68 ResolvedFunction::Type(t) => FunctionTypeOutcome::Typed(t),
69 ResolvedFunction::Unresolved => FunctionTypeOutcome::Unresolved,
70 };
71 }
72
73 if self.function_requested().borrow_mut().insert(key) {
74 self.function_requests()
75 .borrow_mut()
76 .push(FunctionResolutionRequest {
77 source: source.clone(),
78 input: input.shallow_clone(),
79 });
80 }
81 FunctionTypeOutcome::Unknown
82 }
83
84 pub fn function_resolution_requests(&self) -> Vec<FunctionResolutionRequest> {
85 let snap = self.snapshot();
86 let mut paths: Vec<Arc<str>> = snap.graphs.keys().cloned().collect();
87 paths.sort();
88 for path in &paths {
89 let _ = self.graph_analysis(path);
90 }
91 std::mem::take(&mut *self.function_requests().borrow_mut())
92 }
93
94 pub fn set_function_type(&self, source: &str, input: &VariableType, ts_type: Option<&str>) {
95 let key = Self::function_key_str(source, input);
96 let entry = match ts_type.and_then(TsTypeParser::variable_type) {
97 Some(resolved) => ResolvedFunction::Type(resolved),
98 None => ResolvedFunction::Unresolved,
99 };
100 self.function_types().borrow_mut().insert(key, entry);
101 self.invalidate_snapshot();
102 }
103
104 pub(crate) fn function_state(&self, key: FunctionKey) -> u64 {
105 match self.function_types().borrow().get(&key) {
106 None => 0,
107 Some(ResolvedFunction::Unresolved) => 1,
108 Some(ResolvedFunction::Type(t)) => {
109 let mut hasher = std::collections::hash_map::DefaultHasher::new();
110 2u8.hash(&mut hasher);
111 t.hash(&mut hasher);
112 hasher.finish()
113 }
114 }
115 }
116
117 pub(crate) fn function_key(source: &Arc<str>, input: &VariableType) -> FunctionKey {
118 Self::function_key_str(source.as_ref(), input)
119 }
120
121 fn function_key_str(source: &str, input: &VariableType) -> FunctionKey {
122 let mut source_hasher = std::collections::hash_map::DefaultHasher::new();
123 source.hash(&mut source_hasher);
124 let mut input_hasher = std::collections::hash_map::DefaultHasher::new();
125 input.hash(&mut input_hasher);
126 (source_hasher.finish(), input_hasher.finish())
127 }
128}