jellyflow_runtime/profile/
domain.rs1use serde::{Deserialize, Serialize};
2
3use jellyflow_core::core::{EdgeKind, NodeKindKey, PortKey};
4use jellyflow_core::types::TypeDesc;
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
8pub struct GraphProfileMetadata {
9 #[serde(default, skip_serializing_if = "Option::is_none")]
11 pub key: Option<String>,
12 #[serde(default, skip_serializing_if = "Option::is_none")]
14 pub title: Option<String>,
15 #[serde(default, skip_serializing_if = "Vec::is_empty")]
17 pub node_fields: Vec<NodeFieldSchemaSet>,
18 #[serde(default, skip_serializing_if = "Vec::is_empty")]
20 pub variable_surfaces: Vec<VariableSurfaceDescriptor>,
21 #[serde(default, skip_serializing_if = "Vec::is_empty")]
23 pub connection_rules: Vec<ConnectionRuleDescriptor>,
24}
25
26impl GraphProfileMetadata {
27 pub fn new(key: impl Into<String>, title: impl Into<String>) -> Self {
28 Self {
29 key: Some(key.into()),
30 title: Some(title.into()),
31 ..Self::default()
32 }
33 }
34
35 pub fn with_node_fields(mut self, fields: NodeFieldSchemaSet) -> Self {
36 self.node_fields.push(fields);
37 self
38 }
39
40 pub fn with_variable_surface(mut self, surface: VariableSurfaceDescriptor) -> Self {
41 self.variable_surfaces.push(surface);
42 self
43 }
44
45 pub fn with_connection_rule(mut self, rule: ConnectionRuleDescriptor) -> Self {
46 self.connection_rules.push(rule);
47 self
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
53pub struct NodeFieldSchemaSet {
54 pub node_kind: NodeKindKey,
55 #[serde(default, skip_serializing_if = "Vec::is_empty")]
56 pub fields: Vec<FieldSchema>,
57}
58
59impl NodeFieldSchemaSet {
60 pub fn new(node_kind: impl Into<NodeKindKey>) -> Self {
61 Self {
62 node_kind: node_kind.into(),
63 fields: Vec::new(),
64 }
65 }
66
67 pub fn with_field(mut self, field: FieldSchema) -> Self {
68 self.fields.push(field);
69 self
70 }
71}
72
73#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75pub struct FieldSchema {
76 pub key: String,
77 pub label: String,
78 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub ty: Option<TypeDesc>,
80 #[serde(default)]
81 pub required: bool,
82 #[serde(default, skip_serializing_if = "Vec::is_empty")]
83 pub hints: Vec<ValidationHint>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub port_anchor: Option<PortKey>,
86}
87
88impl FieldSchema {
89 pub fn new(key: impl Into<String>, label: impl Into<String>) -> Self {
90 Self {
91 key: key.into(),
92 label: label.into(),
93 ty: None,
94 required: false,
95 hints: Vec::new(),
96 port_anchor: None,
97 }
98 }
99
100 pub fn with_type(mut self, ty: TypeDesc) -> Self {
101 self.ty = Some(ty);
102 self
103 }
104
105 pub fn required(mut self) -> Self {
106 self.required = true;
107 self
108 }
109
110 pub fn with_hint(mut self, hint: ValidationHint) -> Self {
111 self.hints.push(hint);
112 self
113 }
114
115 pub fn with_port_anchor(mut self, port: impl Into<PortKey>) -> Self {
116 self.port_anchor = Some(port.into());
117 self
118 }
119}
120
121#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
123pub struct ValidationHint {
124 pub code: String,
125 pub message: String,
126}
127
128impl ValidationHint {
129 pub fn new(code: impl Into<String>, message: impl Into<String>) -> Self {
130 Self {
131 code: code.into(),
132 message: message.into(),
133 }
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
139pub struct VariableSurfaceDescriptor {
140 pub key: String,
141 pub label: String,
142 #[serde(default, skip_serializing_if = "Vec::is_empty")]
143 pub variables: Vec<VariableDescriptor>,
144}
145
146impl VariableSurfaceDescriptor {
147 pub fn new(key: impl Into<String>, label: impl Into<String>) -> Self {
148 Self {
149 key: key.into(),
150 label: label.into(),
151 variables: Vec::new(),
152 }
153 }
154
155 pub fn with_variable(mut self, variable: VariableDescriptor) -> Self {
156 self.variables.push(variable);
157 self
158 }
159}
160
161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
163pub struct VariableDescriptor {
164 pub key: String,
165 pub label: String,
166 #[serde(default, skip_serializing_if = "Option::is_none")]
167 pub ty: Option<TypeDesc>,
168}
169
170impl VariableDescriptor {
171 pub fn new(key: impl Into<String>, label: impl Into<String>) -> Self {
172 Self {
173 key: key.into(),
174 label: label.into(),
175 ty: None,
176 }
177 }
178
179 pub fn with_type(mut self, ty: TypeDesc) -> Self {
180 self.ty = Some(ty);
181 self
182 }
183}
184
185#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
187pub struct ConnectionRuleDescriptor {
188 pub key: String,
189 pub label: String,
190 #[serde(default, skip_serializing_if = "Option::is_none")]
191 pub edge_kind: Option<EdgeKind>,
192}
193
194impl ConnectionRuleDescriptor {
195 pub fn new(key: impl Into<String>, label: impl Into<String>) -> Self {
196 Self {
197 key: key.into(),
198 label: label.into(),
199 edge_kind: None,
200 }
201 }
202
203 pub fn for_edge_kind(mut self, edge_kind: EdgeKind) -> Self {
204 self.edge_kind = Some(edge_kind);
205 self
206 }
207}