use serde::{Deserialize, Serialize};
use crate::{
ComponentId, KnownConfigName, LatticeTarget, LinkName, Result, WitInterface, WitNamespace,
WitPackage,
};
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize, Hash)]
#[non_exhaustive]
pub struct Link {
pub(crate) source_id: ComponentId,
pub(crate) target: LatticeTarget,
#[serde(default = "default_link_name")]
pub(crate) name: LinkName,
pub(crate) wit_namespace: WitNamespace,
pub(crate) wit_package: WitPackage,
pub(crate) interfaces: Vec<WitInterface>,
#[serde(default)]
pub(crate) source_config: Vec<KnownConfigName>,
#[serde(default)]
pub(crate) target_config: Vec<KnownConfigName>,
}
impl Link {
#[must_use]
pub fn source_id(&self) -> &str {
&self.source_id
}
#[must_use]
pub fn target(&self) -> &str {
&self.target
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
#[must_use]
pub fn wit_namespace(&self) -> &str {
&self.wit_namespace
}
#[must_use]
pub fn wit_package(&self) -> &str {
&self.wit_package
}
#[must_use]
pub fn interfaces(&self) -> &Vec<String> {
&self.interfaces
}
#[must_use]
pub fn source_config(&self) -> &Vec<String> {
&self.source_config
}
#[must_use]
pub fn target_config(&self) -> &Vec<String> {
&self.target_config
}
#[must_use]
pub fn builder() -> LinkBuilder {
LinkBuilder::default()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[non_exhaustive]
pub struct LinkBuilder {
source_id: Option<ComponentId>,
target: Option<LatticeTarget>,
name: Option<LinkName>,
wit_namespace: Option<WitNamespace>,
wit_package: Option<WitPackage>,
interfaces: Option<Vec<WitInterface>>,
source_config: Option<Vec<KnownConfigName>>,
target_config: Option<Vec<KnownConfigName>>,
}
impl LinkBuilder {
#[must_use]
pub fn source_id(mut self, v: &str) -> Self {
self.source_id = Some(v.into());
self
}
#[must_use]
pub fn target(mut self, v: &str) -> Self {
self.target = Some(v.into());
self
}
#[must_use]
pub fn name(mut self, v: &str) -> Self {
self.name = Some(v.into());
self
}
#[must_use]
pub fn wit_namespace(mut self, v: &str) -> Self {
self.wit_namespace = Some(v.into());
self
}
#[must_use]
pub fn wit_package(mut self, v: &str) -> Self {
self.wit_package = Some(v.into());
self
}
#[must_use]
pub fn interfaces(mut self, v: Vec<String>) -> Self {
self.interfaces = Some(v);
self
}
#[must_use]
pub fn source_config(mut self, v: Vec<String>) -> Self {
self.source_config = Some(v);
self
}
#[must_use]
pub fn target_config(mut self, v: Vec<String>) -> Self {
self.target_config = Some(v);
self
}
pub fn build(self) -> Result<Link> {
Ok(Link {
source_id: self
.source_id
.ok_or_else(|| "source id is required for creating links".to_string())?,
target: self
.target
.ok_or_else(|| "target is required for creating links".to_string())?,
name: self
.name
.ok_or_else(|| "name is required for creating links".to_string())?,
wit_namespace: self
.wit_namespace
.ok_or_else(|| "WIT namespace is required for creating links".to_string())?,
wit_package: self
.wit_package
.ok_or_else(|| "WIT package is required for creating links".to_string())?,
interfaces: self.interfaces.unwrap_or_default(),
source_config: self.source_config.unwrap_or_default(),
target_config: self.target_config.unwrap_or_default(),
})
}
}
pub(crate) fn default_link_name() -> LinkName {
"default".to_string()
}
#[cfg(test)]
mod tests {
use super::Link;
#[test]
fn link_builder() {
assert_eq!(
Link {
source_id: "source_id".into(),
target: "target".into(),
name: "name".into(),
wit_namespace: "wit_namespace".into(),
wit_package: "wit_package".into(),
interfaces: vec!["i".into()],
source_config: vec!["sc".into()],
target_config: vec!["tc".into()]
},
Link::builder()
.source_id("source_id")
.target("target")
.name("name")
.wit_namespace("wit_namespace")
.wit_package("wit_package")
.interfaces(vec!["i".into()])
.source_config(vec!["sc".into()])
.target_config(vec!["tc".into()])
.build()
.unwrap()
);
}
}