Skip to main content

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}