wick_config/config/component_config/
composite.rs

1use std::borrow::Cow;
2use std::collections::HashMap;
3
4use flow_expression_parser::ast::{self};
5use wick_interface_types::{Field, OperationSignatures};
6
7use crate::config::components::{ComponentConfig, OperationConfig};
8use crate::config::{self, ExecutionSettings, LiquidJsonConfig};
9
10#[derive(
11  Debug,
12  Default,
13  Clone,
14  derive_asset_container::AssetManager,
15  derive_builder::Builder,
16  property::Property,
17  serde::Serialize,
18)]
19#[property(get(public), set(public), mut(public, suffix = "_mut"))]
20#[builder(setter(into))]
21#[asset(asset(crate::config::AssetReference))]
22#[must_use]
23/// The internal representation of a Wick manifest.
24pub struct CompositeComponentImplementation {
25  /// The operations defined by the component.
26  #[asset(skip)]
27  #[builder(default)]
28  #[property(skip)]
29  #[serde(skip_serializing_if = "Vec::is_empty")]
30  pub(crate) operations: Vec<FlowOperation>,
31
32  /// The configuration for the component.
33  #[asset(skip)]
34  #[builder(default)]
35  #[serde(skip_serializing_if = "Vec::is_empty")]
36  pub(crate) config: Vec<Field>,
37
38  /// A component or components this component inherits operations from.
39  #[asset(skip)]
40  #[builder(default)]
41  #[serde(skip_serializing_if = "Vec::is_empty")]
42  pub(crate) extends: Vec<String>,
43}
44
45impl CompositeComponentImplementation {
46  /// Get a [FlowOperation] by name.
47  #[must_use]
48  pub fn flow(&self, name: &str) -> Option<&FlowOperation> {
49    self.operations.iter().find(|n| n.name() == name)
50  }
51}
52
53impl OperationSignatures for CompositeComponentImplementation {
54  fn operation_signatures(&self) -> Vec<wick_interface_types::OperationSignature> {
55    self.operations.iter().cloned().map(Into::into).collect()
56  }
57}
58
59impl ComponentConfig for CompositeComponentImplementation {
60  type Operation = FlowOperation;
61
62  fn operations(&self) -> &[Self::Operation] {
63    &self.operations
64  }
65
66  fn operations_mut(&mut self) -> &mut Vec<Self::Operation> {
67    &mut self.operations
68  }
69}
70
71impl OperationConfig for FlowOperation {
72  fn name(&self) -> &str {
73    &self.name
74  }
75
76  fn inputs(&self) -> Cow<Vec<Field>> {
77    Cow::Borrowed(&self.inputs)
78  }
79
80  fn outputs(&self) -> Cow<Vec<Field>> {
81    Cow::Borrowed(&self.outputs)
82  }
83}
84
85impl From<FlowOperation> for wick_interface_types::OperationSignature {
86  fn from(operation: FlowOperation) -> Self {
87    Self::new(operation.name, operation.inputs, operation.outputs, operation.config)
88  }
89}
90
91#[derive(Debug, Clone, PartialEq, derive_builder::Builder, Default, property::Property, serde::Serialize)]
92#[property(get(public), set(private), mut(public, suffix = "_mut"))]
93#[builder(setter(into))]
94/// A FlowOperation is an operation definition whose implementation is defined by
95/// connecting other components together in a flow or set of pipelines.
96#[must_use]
97pub struct FlowOperation {
98  /// The name of the schematic.
99  #[property(skip)]
100  pub(crate) name: String,
101
102  /// A list of the input types for the operation.
103  #[builder(default)]
104  #[property(skip)]
105  #[serde(skip_serializing_if = "Vec::is_empty")]
106  pub(crate) inputs: Vec<Field>,
107
108  /// A list of the input types for the operation.
109  #[builder(default)]
110  #[property(skip)]
111  #[serde(skip_serializing_if = "Vec::is_empty")]
112  pub(crate) outputs: Vec<Field>,
113
114  /// Any configuration required for the component to operate.
115  #[builder(default)]
116  #[serde(skip_serializing_if = "Vec::is_empty")]
117  pub(crate) config: Vec<Field>,
118
119  /// A mapping of instance names to the components they refer to.
120  #[builder(default)]
121  #[serde(skip_serializing_if = "HashMap::is_empty")]
122  pub(crate) instances: HashMap<String, InstanceReference>,
123
124  /// A list of connections from and to ports on instances defined in the instance map.
125  #[builder(default)]
126  #[serde(skip_serializing_if = "Vec::is_empty")]
127  pub(crate) expressions: Vec<ast::FlowExpression>,
128
129  /// Additional flows scoped to this operation.
130  #[builder(default)]
131  #[serde(skip_serializing_if = "Vec::is_empty")]
132  pub(crate) flows: Vec<FlowOperation>,
133}
134
135impl From<FlowOperation> for config::OperationDefinition {
136  fn from(value: FlowOperation) -> Self {
137    Self {
138      name: value.name,
139      inputs: value.inputs,
140      outputs: value.outputs,
141      config: value.config,
142    }
143  }
144}
145
146#[derive(Debug, Clone, PartialEq, property::Property, serde::Serialize)]
147#[property(get(public), set(private), mut(disable))]
148/// A definition of a component used to reference a component registered under a collection.
149/// Note: [InstanceReference] include embed the concept of a namespace so two identical.
150/// components registered on different namespaces will not be equal.
151pub struct InstanceReference {
152  /// The operation's name.
153  pub(crate) name: String,
154  /// The id of the component.
155  pub(crate) component_id: String,
156  /// Data associated with the component instance.
157  #[serde(skip_serializing_if = "Option::is_none")]
158  pub(crate) data: Option<LiquidJsonConfig>,
159  /// Per-operation settings that override global execution settings.
160  #[serde(skip_serializing_if = "Option::is_none")]
161  pub(crate) settings: Option<ExecutionSettings>,
162}
163
164impl InstanceReference {
165  /// Returns the fully qualified ID for the component, i.e. namespace::name.
166  #[must_use]
167  pub fn id(&self) -> String {
168    format!("{}::{}", self.component_id, self.name)
169  }
170}
171
172impl std::fmt::Display for InstanceReference {
173  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174    write!(f, "{}", self.id())
175  }
176}