distillation_shortcut_unit/
material_port.rs

1use crate::shared_unit_data::*;
2use crate::distillation_shortcut_unit::DistillationShortcutUnit;
3use cobia::*;
4
5/// The MaterialPort class implements a CAPE-OPEN 1.2 material port.
6///
7/// It connects to a valid CAPE-OPEN 1.2 compliant material object provided by the PME.
8
9
10#[cape_object_implementation(
11		interfaces = {
12			cape_open_1_2::ICapeIdentification,
13			cape_open_1_2::ICapeUnitPort,
14		},
15		create_arguments = {
16			name,
17			description,
18			is_inlet,
19			shared_unit_data
20		}
21  )] 
22pub struct MaterialPort {
23	/// The name of the port
24	name: CapeStringImpl,
25	/// The description of the port
26	description: CapeStringImpl,
27	/// The connected material object, if any
28	connected_object: Option<cape_open_1_2::CapeThermoMaterial>,
29	/// Indicates whether this port is an inlet (true) or an outlet (false)
30	is_inlet : bool,
31	/// Shared data for the unit, containing unit-specific information
32	shared_unit_data: SharedUnitDataRef, 
33}
34
35impl MaterialPort {
36
37	/// Get the connected material object, if any.
38	///
39	/// # Returns:
40	/// * The connected material object, or `None` if the port is not connected to any material object.
41
42	pub(crate) fn get_connected_material(&self) -> Option<cape_open_1_2::CapeThermoMaterial> {
43		self.connected_object.clone()
44	}
45
46	/// Get the name of the port.
47	///
48	/// # Returns:
49	/// * A reference to the name of the port as a `CapeStringImpl`.
50
51	pub(crate) fn get_name(&self) -> &CapeStringImpl {
52		&self.name
53	}
54
55}
56
57impl std::fmt::Display for MaterialPort {
58
59	/// Format the MaterialPort as a string for display purposes.
60	///
61	/// The std::fmt::Display interface is used when generating the 
62	/// source name of the object that raises an error.
63	///
64	/// # Arguments:
65	/// * `f` - A mutable reference to a `std::fmt::Formatter` where the formatted string will be written.
66	///
67	/// # Returns:
68	/// * A `std::fmt::Result` indicating the success or failure of the formatting operation.
69
70	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        write!(f,"Port '{}' of {} unit '{}'",self.name, DistillationShortcutUnit::NAME, self.shared_unit_data.borrow().name)
72    }
73
74}
75
76impl cape_open_1_2::ICapeIdentification for MaterialPort {
77
78	/// Get the name of the component.
79	///
80	/// # Arguments:
81	/// * `name` - A mutable reference to a `CapeStringOut` where the name will be set.
82	///
83	/// # Returns:
84	/// * A `Result` indicating success or failure. If successful, the name is set in `name`.
85
86	fn get_component_name(&mut self,name:&mut CapeStringOut) -> Result<(), COBIAError> {
87		name.set(&self.name)?;
88		Ok(())
89	}
90
91	/// Get the description of the component.
92	///
93	/// # Arguments:
94	/// * `description` - A mutable reference to a `CapeStringOut` where the description will be set.
95	///
96	/// # Returns:
97	/// * A `Result` indicating success or failure. If successful, the description is set in `description`.
98
99	fn get_component_description(&mut self,description:&mut CapeStringOut) -> Result<(), COBIAError> {
100		description.set(&self.description)?;
101		Ok(())
102	}
103
104	/// Set the name of the component.
105	///
106	/// This method is not allowed for this port implementation and will return an error.
107
108	fn set_component_name(&mut self, _name: &CapeStringIn) -> Result<(), COBIAError> {
109		Err(cobia::COBIAError::Code(cobia::COBIAERR_DENIED))
110	}
111
112	/// Set the description of the component.
113	///
114	/// This method is not allowed for this port implementation and will return an error.
115
116	fn set_component_description(&mut self, _desc: &CapeStringIn) -> Result<(), COBIAError> {
117		Err(cobia::COBIAError::Code(cobia::COBIAERR_DENIED))
118	}
119}
120
121impl cape_open_1_2::ICapeUnitPort for MaterialPort {
122
123	/// Get the port type.
124	///
125	/// # Returns:
126	/// * A `Result` containing the port type, which is always `CapeMaterial` for this implementation.
127
128    fn get_port_type(&mut self) -> Result<cape_open_1_2::CapePortType,COBIAError> {
129        Ok(cape_open_1_2::CapePortType::CapeMaterial)
130    }
131
132	/// Get the direction of the port.
133	///
134	/// # Returns:
135	/// * A `Result` containing the port direction, which is either `CapeInlet` or `CapeOutlet`.
136
137    fn get_direction(&mut self) -> Result<cape_open_1_2::CapePortDirection,COBIAError> {
138        Ok(
139			match self.is_inlet {
140				true => cape_open_1_2::CapePortDirection::CapeInlet,
141				false => cape_open_1_2::CapePortDirection::CapeOutlet,
142			}
143		)
144    }
145
146	/// Get the connected object of the port.
147	///
148	/// # Returns:
149	/// * A `Result` containing the connected `CapeObject`, or an error if the port is not connected.
150
151    fn get_connected_object(&mut self) -> Result<cobia::CapeObject,COBIAError> {
152        match self.connected_object {
153			Some(ref connected_object) => {
154				match cobia::CapeObject::from_object(connected_object) {
155					Ok(object) => {
156						Ok(object)
157					},
158					Err(_) => {
159						Err(COBIAError::Message("Object does not expose ICapeInterface".into()))
160					}
161				}
162			},
163			None => {
164				Err(COBIAError::Code(COBIAERR_NOSUCHITEM))
165			}
166		}
167    }
168
169	/// Connect the port to a `CapeObject`.
170	///
171	/// This port will only accept connections to a valid `CapeThermoMaterial` object.
172	///
173	/// # Arguments:
174	/// * `object_to_connect` - The `CapeObject` to connect to the port.
175	///
176	/// # Returns:
177	/// * A `Result` indicating success or failure. If successful, the port is connected to the material object.
178
179    fn connect(&mut self,object_to_connect:cobia::CapeObject) -> Result<(),COBIAError> {
180		let material_object = cape_open_1_2::CapeThermoMaterial::from_object(&object_to_connect);
181		match material_object {
182			Ok(material_object) => {
183					self.connected_object=Some(material_object);
184					self.shared_unit_data.borrow_mut().validation_status = cape_open_1_2::CapeValidationStatus::CapeNotValidated;
185					Ok(())
186				},
187			Err(e) => Err(e),
188		}
189    }
190
191	/// Disconnect the port from its connected object.
192	///
193	/// # Returns:
194	/// * A `Result` indicating success or failure; always succeeds.
195
196    fn disconnect(&mut self) -> Result<(),COBIAError> {
197        self.connected_object=None;
198		self.shared_unit_data.borrow_mut().validation_status = cape_open_1_2::CapeValidationStatus::CapeNotValidated;
199		Ok(())
200    }
201}