ifc_rs/units/
assignment.rs1use std::fmt::Display;
2
3use ifc_rs_verify_derive::IfcVerify;
4
5use crate::{
6 id::IdOr,
7 ifc_type::{IfcType, IfcVerify},
8 parser::{list::IfcList, p_space_or_comment_surrounded, IFCParse, IFCParser},
9 prelude::*,
10};
11
12#[derive(IfcVerify)]
20pub struct UnitAssigment {
21 #[ifc_types(SiUnit, ConversionBasedUnit, DerivedUnit, MonetaryUnit)]
23 pub units: IfcList<Id>,
24}
25
26impl UnitAssigment {
27 pub fn new(units: impl IntoIterator<Item = IdOr<SiUnit>>, ifc: &mut IFC) -> Self {
28 Self {
29 units: IfcList(units.into_iter().map(|u| u.or_insert(ifc).id()).collect()),
30 }
31 }
32}
33
34impl IFCParse for UnitAssigment {
35 fn parse<'a>() -> impl IFCParser<'a, Self> {
36 winnow::seq! {
37 Self {
38 _: p_space_or_comment_surrounded("IFCUNITASSIGNMENT("),
39
40 units: IfcList::parse(),
41
42 _: p_space_or_comment_surrounded(");"),
43 }
44 }
45 }
46}
47
48impl Display for UnitAssigment {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "IFCUNITASSIGNMENT({});", self.units)
51 }
52}
53
54impl IfcType for UnitAssigment {}
55
56#[cfg(test)]
57mod test {
58 use winnow::Parser;
59
60 use super::UnitAssigment;
61 use crate::parser::IFCParse;
62
63 #[test]
64 fn rel_aggregates_round_trip() {
65 let example = "IFCUNITASSIGNMENT((#18,#19,#20));";
66
67 let unit_assignment: UnitAssigment = UnitAssigment::parse().parse(example).unwrap();
68 let str_unit_assignment = unit_assignment.to_string();
69
70 assert_eq!(example, str_unit_assignment);
71 }
72}