protoflow_core/
port_descriptor.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::{
4    prelude::{type_name, Cow, MaybeLabeled, MaybeNamed, String, ToString},
5    InputPort, Message, OutputPort, Port, PortID, PortState,
6};
7
8/// The dataflow direction of a port.
9#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
12pub enum PortDirection {
13    Input,
14    Output,
15}
16
17/// A descriptor for a block port.
18#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize))]
20pub struct PortDescriptor {
21    /// The dataflow direction of this port.
22    pub direction: PortDirection,
23
24    /// The machine-readable name of this port, if any.
25    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
26    pub name: Option<String>,
27
28    /// A human-readable label for this port, if any.
29    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
30    pub label: Option<String>,
31
32    /// The data type for messages on this port.
33    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
34    pub r#type: Option<String>,
35
36    /// The unique identifier for this port.
37    #[cfg_attr(feature = "serde", serde(skip))]
38    pub id: PortID,
39
40    /// The current state of this port.
41    #[cfg_attr(feature = "serde", serde(skip))]
42    pub state: PortState,
43}
44
45impl PortDescriptor {
46    pub fn is_input(&self) -> bool {
47        self.direction == PortDirection::Input
48    }
49
50    pub fn is_output(&self) -> bool {
51        self.direction == PortDirection::Output
52    }
53}
54
55impl MaybeNamed for PortDescriptor {
56    fn name(&self) -> Option<Cow<str>> {
57        self.name.as_deref().map(Cow::Borrowed)
58    }
59}
60
61impl MaybeLabeled for PortDescriptor {
62    fn label(&self) -> Option<Cow<str>> {
63        self.label.as_deref().map(Cow::Borrowed)
64    }
65}
66
67impl Port for PortDescriptor {
68    fn id(&self) -> PortID {
69        self.id
70    }
71
72    fn state(&self) -> PortState {
73        self.state
74    }
75}
76
77impl<T: Message> From<&InputPort<T>> for PortDescriptor {
78    fn from(port: &InputPort<T>) -> Self {
79        Self {
80            direction: PortDirection::Input,
81            name: port.name().map(|s| s.to_string()),
82            label: port.label().map(|s| s.to_string()),
83            r#type: Some(type_name::<T>().to_string()),
84            id: port.id(),
85            state: port.state(),
86        }
87    }
88}
89
90impl<T: Message> From<&OutputPort<T>> for PortDescriptor {
91    fn from(port: &OutputPort<T>) -> Self {
92        Self {
93            direction: PortDirection::Output,
94            name: port.name().map(|s| s.to_string()),
95            label: port.label().map(|s| s.to_string()),
96            r#type: Some(type_name::<T>().to_string()),
97            id: port.id(),
98            state: port.state(),
99        }
100    }
101}