oxihuman_export/
ifc_export.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum IfcClass {
10 IfcProject,
11 IfcSite,
12 IfcBuilding,
13 IfcBuildingStorey,
14 IfcWall,
15 IfcSlab,
16 IfcColumn,
17}
18
19#[derive(Debug, Clone)]
21pub struct IfcEntity {
22 pub id: u32,
23 pub class: IfcClass,
24 pub name: String,
25 pub attributes: Vec<String>,
26}
27
28#[derive(Debug, Clone, Default)]
30pub struct IfcExport {
31 pub schema: String,
32 pub entities: Vec<IfcEntity>,
33}
34
35pub fn new_ifc_export(schema: &str) -> IfcExport {
37 IfcExport {
38 schema: schema.to_string(),
39 entities: Vec::new(),
40 }
41}
42
43pub fn add_ifc_entity(export: &mut IfcExport, class: IfcClass, name: &str) -> u32 {
45 let id = export.entities.len() as u32 + 1;
46 export.entities.push(IfcEntity {
47 id,
48 class,
49 name: name.to_string(),
50 attributes: Vec::new(),
51 });
52 id
53}
54
55pub fn ifc_entity_count(export: &IfcExport) -> usize {
57 export.entities.len()
58}
59
60pub fn ifc_count_class(export: &IfcExport, class: IfcClass) -> usize {
62 export.entities.iter().filter(|e| e.class == class).count()
63}
64
65pub fn ifc_header(export: &IfcExport) -> String {
67 format!(
68 "ISO-10303-21;\nHEADER;\nFILE_SCHEMA(('{}'));\nENDSEC;\nDATA;",
69 export.schema
70 )
71}
72
73pub fn ifc_entity_line(entity: &IfcEntity) -> String {
75 let class_name = match entity.class {
76 IfcClass::IfcProject => "IFCPROJECT",
77 IfcClass::IfcSite => "IFCSITE",
78 IfcClass::IfcBuilding => "IFCBUILDING",
79 IfcClass::IfcBuildingStorey => "IFCBUILDINGSTOREY",
80 IfcClass::IfcWall => "IFCWALL",
81 IfcClass::IfcSlab => "IFCSLAB",
82 IfcClass::IfcColumn => "IFCCOLUMN",
83 };
84 format!("#{} = {}('{}');", entity.id, class_name, entity.name)
85}
86
87pub fn validate_ifc(export: &IfcExport) -> bool {
89 export
90 .entities
91 .iter()
92 .any(|e| e.class == IfcClass::IfcProject)
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_new_export_empty() {
101 let exp = new_ifc_export("IFC4");
102 assert_eq!(ifc_entity_count(&exp), 0);
103 }
104
105 #[test]
106 fn test_add_entity_returns_id() {
107 let mut exp = new_ifc_export("IFC4");
108 let id = add_ifc_entity(&mut exp, IfcClass::IfcProject, "MyProject");
109 assert_eq!(id, 1);
110 }
111
112 #[test]
113 fn test_entity_count() {
114 let mut exp = new_ifc_export("IFC4");
115 add_ifc_entity(&mut exp, IfcClass::IfcProject, "P");
116 add_ifc_entity(&mut exp, IfcClass::IfcBuilding, "B");
117 assert_eq!(ifc_entity_count(&exp), 2);
118 }
119
120 #[test]
121 fn test_count_class() {
122 let mut exp = new_ifc_export("IFC4");
123 add_ifc_entity(&mut exp, IfcClass::IfcWall, "W1");
124 add_ifc_entity(&mut exp, IfcClass::IfcWall, "W2");
125 add_ifc_entity(&mut exp, IfcClass::IfcSlab, "S1");
126 assert_eq!(ifc_count_class(&exp, IfcClass::IfcWall), 2);
127 }
128
129 #[test]
130 fn test_header_contains_schema() {
131 let exp = new_ifc_export("IFC4");
132 assert!(ifc_header(&exp).contains("IFC4"));
133 }
134
135 #[test]
136 fn test_entity_line_wall() {
137 let mut exp = new_ifc_export("IFC4");
138 add_ifc_entity(&mut exp, IfcClass::IfcWall, "MyWall");
139 let line = ifc_entity_line(&exp.entities[0]);
140 assert!(line.contains("IFCWALL"));
141 assert!(line.contains("MyWall"));
142 }
143
144 #[test]
145 fn test_validate_with_project() {
146 let mut exp = new_ifc_export("IFC4");
147 add_ifc_entity(&mut exp, IfcClass::IfcProject, "Proj");
148 assert!(validate_ifc(&exp));
149 }
150
151 #[test]
152 fn test_validate_without_project() {
153 let mut exp = new_ifc_export("IFC4");
154 add_ifc_entity(&mut exp, IfcClass::IfcWall, "W");
155 assert!(!validate_ifc(&exp));
156 }
157
158 #[test]
159 fn test_schema_stored() {
160 let exp = new_ifc_export("IFC2X3");
161 assert_eq!(exp.schema, "IFC2X3");
162 }
163}