ifc_systems/flow/direction.rs
1//! `IfcFlowDirectionEnum` and what it licenses.
2//!
3//! The enum is a port attribute, but its MEANING is a flow concern: it decides
4//! which way an edge may be walked. Keeping the semantics here rather than on
5//! the port keeps "what the file says" separate from "what that implies".
6
7use ifc_model::Value;
8
9/// Which way material or energy moves through a port.
10///
11/// A missing direction is [`FlowDirection::NotDefined`] rather than an assumed
12/// default. Guessing `Source` would invent a direction the file never stated
13/// and orient edges that have no stated orientation, which is worse than
14/// admitting the network is partly undirected.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
16pub enum FlowDirection {
17 /// Material leaves the element through this port.
18 Source,
19 /// Material enters the element through this port.
20 Sink,
21 /// Bidirectional.
22 SourceAndSink,
23 /// Stated as NOTDEFINED, or not stated at all.
24 NotDefined,
25}
26
27impl FlowDirection {
28 /// Read the enum from an attribute slot.
29 pub(crate) fn parse(value: Option<&Value>) -> Self {
30 match value {
31 Some(Value::Enum(name)) => match name.to_ascii_uppercase().as_str() {
32 "SOURCE" => Self::Source,
33 "SINK" => Self::Sink,
34 "SOURCEANDSINK" => Self::SourceAndSink,
35 _ => Self::NotDefined,
36 },
37 _ => Self::NotDefined,
38 }
39 }
40
41 /// Whether material may LEAVE the element through this port.
42 ///
43 /// `NotDefined` is false in both directions. That is deliberate: an
44 /// undirected port cannot orient an edge, and pretending it can would
45 /// manufacture flow paths a reviewer cannot trace back to the file.
46 pub fn emits(self) -> bool {
47 matches!(self, Self::Source | Self::SourceAndSink)
48 }
49
50 /// Whether material may ENTER the element through this port.
51 pub fn accepts(self) -> bool {
52 matches!(self, Self::Sink | Self::SourceAndSink)
53 }
54
55 /// Whether the file stated a direction at all.
56 pub fn is_stated(self) -> bool {
57 !matches!(self, Self::NotDefined)
58 }
59}