use std::borrow::Cow;
use std::collections::HashMap;
use flow_expression_parser::ast::{self};
use wick_interface_types::{Field, OperationSignatures};
use crate::config::components::{ComponentConfig, OperationConfig};
use crate::config::{self, ExecutionSettings, LiquidJsonConfig};
#[derive(
Debug,
Default,
Clone,
derive_asset_container::AssetManager,
derive_builder::Builder,
property::Property,
serde::Serialize,
)]
#[property(get(public), set(public), mut(public, suffix = "_mut"))]
#[builder(setter(into))]
#[asset(asset(crate::config::AssetReference))]
#[must_use]
pub struct CompositeComponentImplementation {
#[asset(skip)]
#[builder(default)]
#[property(skip)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) operations: Vec<FlowOperation>,
#[asset(skip)]
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) config: Vec<Field>,
#[asset(skip)]
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) extends: Vec<String>,
}
impl CompositeComponentImplementation {
#[must_use]
pub fn flow(&self, name: &str) -> Option<&FlowOperation> {
self.operations.iter().find(|n| n.name() == name)
}
}
impl OperationSignatures for CompositeComponentImplementation {
fn operation_signatures(&self) -> Vec<wick_interface_types::OperationSignature> {
self.operations.iter().cloned().map(Into::into).collect()
}
}
impl ComponentConfig for CompositeComponentImplementation {
type Operation = FlowOperation;
fn operations(&self) -> &[Self::Operation] {
&self.operations
}
fn operations_mut(&mut self) -> &mut Vec<Self::Operation> {
&mut self.operations
}
}
impl OperationConfig for FlowOperation {
fn name(&self) -> &str {
&self.name
}
fn inputs(&self) -> Cow<Vec<Field>> {
Cow::Borrowed(&self.inputs)
}
fn outputs(&self) -> Cow<Vec<Field>> {
Cow::Borrowed(&self.outputs)
}
}
impl From<FlowOperation> for wick_interface_types::OperationSignature {
fn from(operation: FlowOperation) -> Self {
Self::new(operation.name, operation.inputs, operation.outputs, operation.config)
}
}
#[derive(Debug, Clone, PartialEq, derive_builder::Builder, Default, property::Property, serde::Serialize)]
#[property(get(public), set(private), mut(public, suffix = "_mut"))]
#[builder(setter(into))]
#[must_use]
pub struct FlowOperation {
#[property(skip)]
pub(crate) name: String,
#[builder(default)]
#[property(skip)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) inputs: Vec<Field>,
#[builder(default)]
#[property(skip)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) outputs: Vec<Field>,
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) config: Vec<Field>,
#[builder(default)]
#[serde(skip_serializing_if = "HashMap::is_empty")]
pub(crate) instances: HashMap<String, InstanceReference>,
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) expressions: Vec<ast::FlowExpression>,
#[builder(default)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub(crate) flows: Vec<FlowOperation>,
}
impl From<FlowOperation> for config::OperationDefinition {
fn from(value: FlowOperation) -> Self {
Self {
name: value.name,
inputs: value.inputs,
outputs: value.outputs,
config: value.config,
}
}
}
#[derive(Debug, Clone, PartialEq, property::Property, serde::Serialize)]
#[property(get(public), set(private), mut(disable))]
pub struct InstanceReference {
pub(crate) name: String,
pub(crate) component_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) data: Option<LiquidJsonConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) settings: Option<ExecutionSettings>,
}
impl InstanceReference {
#[must_use]
pub fn id(&self) -> String {
format!("{}::{}", self.component_id, self.name)
}
}
impl std::fmt::Display for InstanceReference {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.id())
}
}