1use std::string::String;
8use std::vec::Vec;
9
10use crate::foundation::{KnotKind, NumericPath};
11
12use crate::ValidationError;
13
14#[cfg(feature = "schema")]
15use schemars::JsonSchema;
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Serialize};
18#[cfg(feature = "schema")]
19use std::borrow::ToOwned;
20
21#[derive(Clone, Debug, PartialEq, Eq)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[cfg_attr(feature = "schema", derive(JsonSchema))]
25pub struct PortRefDef {
26 pub knot: String,
28 pub port: String,
30}
31
32impl PortRefDef {
33 pub fn new(knot: impl Into<String>, port: impl Into<String>) -> Self {
35 Self {
36 knot: knot.into(),
37 port: port.into(),
38 }
39 }
40}
41
42#[derive(Clone, Debug, PartialEq)]
44#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
45#[cfg_attr(feature = "schema", derive(JsonSchema))]
46pub struct KnotDef {
47 pub id: String,
49 pub kind: KnotKind,
51}
52
53#[derive(Clone, Debug, PartialEq, Eq)]
55#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
56#[cfg_attr(feature = "schema", derive(JsonSchema))]
57pub struct ThreadDef {
58 pub from: PortRefDef,
60 pub to: PortRefDef,
62}
63
64#[derive(Clone, Debug, PartialEq)]
66#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
67#[cfg_attr(feature = "schema", derive(JsonSchema))]
68pub struct WeaveDef {
69 pub id: String,
71 pub numeric: NumericPath,
73 pub knots: Vec<KnotDef>,
75 pub threads: Vec<ThreadDef>,
77}
78
79#[derive(Clone, Debug, PartialEq)]
81pub struct Weave {
82 id: String,
83 numeric: NumericPath,
84 knots: Vec<KnotDef>,
85 threads: Vec<ThreadDef>,
86}
87
88impl Weave {
89 pub fn builder(id: impl Into<String>) -> Result<crate::WeaveBuilder, crate::BuildError> {
91 crate::WeaveBuilder::new(id)
92 }
93
94 pub fn compose(
101 id: impl Into<String>,
102 compose: impl FnOnce(&mut crate::Composer) -> Result<(), crate::BuildError>,
103 ) -> Result<Self, crate::ComposeError> {
104 let mut composer = crate::Composer::new(id)?;
105 compose(&mut composer)?;
106 Ok(composer.build()?)
107 }
108
109 pub fn id(&self) -> &str {
111 &self.id
112 }
113
114 pub fn numeric(&self) -> NumericPath {
116 self.numeric
117 }
118
119 pub fn knots(&self) -> &[KnotDef] {
121 &self.knots
122 }
123
124 pub fn threads(&self) -> &[ThreadDef] {
126 &self.threads
127 }
128
129 pub fn to_def(&self) -> WeaveDef {
131 WeaveDef {
132 id: self.id.clone(),
133 numeric: self.numeric,
134 knots: self.knots.clone(),
135 threads: self.threads.clone(),
136 }
137 }
138
139 pub(crate) fn from_validated(def: WeaveDef) -> Self {
140 Self {
141 id: def.id,
142 numeric: def.numeric,
143 knots: def.knots,
144 threads: def.threads,
145 }
146 }
147}
148
149impl TryFrom<WeaveDef> for Weave {
150 type Error = ValidationError;
151
152 fn try_from(def: WeaveDef) -> Result<Self, Self::Error> {
153 crate::authoring::validate::validate_def(&def)?;
154 Ok(Self::from_validated(def))
155 }
156}
157
158impl From<Weave> for WeaveDef {
159 fn from(weave: Weave) -> Self {
160 Self {
161 id: weave.id,
162 numeric: weave.numeric,
163 knots: weave.knots,
164 threads: weave.threads,
165 }
166 }
167}