1use std::{fmt::Display, str::FromStr as _};
2
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6use crate::{Graph, PortId};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct EdgeId(Uuid);
10
11impl Display for EdgeId {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 write!(f, "{}", self.0)
14 }
15}
16
17impl EdgeId {
18 pub fn new() -> Self {
19 Self(Uuid::new_v4())
20 }
21 pub fn from_string(s: impl Into<String>) -> Option<Self> {
22 let string = s.into();
23 Uuid::from_str(&string).ok().map(Self)
24 }
25 pub fn from_uuid(uuid: Uuid) -> Self {
26 Self(uuid)
27 }
28
29 pub fn as_uuid(&self) -> &Uuid {
30 &self.0
31 }
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct Edge {
36 pub id: EdgeId,
37 pub source_port: PortId,
38
39 pub target_port: PortId,
40}
41
42impl Edge {
43 pub fn new() -> Self {
44 Self {
45 id: EdgeId::new(),
46 source_port: PortId::new(),
47 target_port: PortId::new(),
48 }
49 }
50 pub fn source(mut self, port: PortId) -> Self {
51 self.source_port = port;
52 self
53 }
54 pub fn target(mut self, port: PortId) -> Self {
55 self.target_port = port;
56 self
57 }
58}
59
60pub struct EdgeBuilder {
61 source: Option<PortId>,
62 target: Option<PortId>,
63}
64
65impl EdgeBuilder {
66 pub fn new() -> Self {
67 Self {
68 source: None,
69 target: None,
70 }
71 }
72
73 pub fn source(mut self, port: PortId) -> Self {
74 self.source = Some(port);
75 self
76 }
77
78 pub fn target(mut self, port: PortId) -> Self {
79 self.target = Some(port);
80 self
81 }
82
83 pub fn build(self, graph: &mut Graph) -> Option<EdgeId> {
84 let source = self.source?;
85 let target = self.target?;
86
87 let edge_id = graph.next_edge_id();
88
89 graph.edges.insert(
90 edge_id,
91 Edge {
92 id: edge_id,
93 source_port: source,
94 target_port: target,
95 },
96 );
97
98 Some(edge_id)
99 }
100}