bloq_utils/port.rs
1use strum::{Display, EnumString};
2
3/// Direction assigned to an open port.
4///
5/// Temporal ports may stay [`Auto`](Self::Auto), because their direction is
6/// determined by time. Spatial ports must choose [`Input`](Self::Input),
7/// [`Output`](Self::Output), or [`Multiplex`](Self::Multiplex) explicitly.
8#[derive(
9 Debug,
10 Default,
11 Clone,
12 Copy,
13 PartialEq,
14 Eq,
15 Hash,
16 PartialOrd,
17 Ord,
18 serde::Serialize,
19 serde::Deserialize,
20 EnumString,
21 Display,
22)]
23#[strum(ascii_case_insensitive)]
24pub enum PortRole {
25 /// Infer the role from temporal direction.
26 #[default]
27 Auto,
28 /// Input boundary.
29 Input,
30 /// Output boundary.
31 Output,
32 /// Z-split boundary: input plus a correlated single-qubit output.
33 Multiplex,
34}
35
36impl PortRole {
37 /// Returns whether this role exposes an input boundary.
38 #[must_use]
39 pub const fn has_input_boundary(self) -> bool {
40 matches!(self, Self::Input | Self::Multiplex)
41 }
42
43 /// Returns whether this role exposes an output boundary.
44 #[must_use]
45 pub const fn has_output_boundary(self) -> bool {
46 matches!(self, Self::Output | Self::Multiplex)
47 }
48
49 /// Returns the lowercase serialized spelling.
50 #[must_use]
51 pub const fn as_str(self) -> &'static str {
52 match self {
53 Self::Auto => "auto",
54 Self::Input => "input",
55 Self::Output => "output",
56 Self::Multiplex => "multiplex",
57 }
58 }
59}