ifc_alignment/authoring/
layout.rs1use ifc_model::{Entity, EntityId, Transaction, Value};
12
13use super::{finite, guid, invalid};
14use crate::error::AlignmentError;
15use crate::slot;
16
17fn product_attrs(
19 type_name: &'static str,
20 arity: usize,
21 global_id: &str,
22 name: Option<&str>,
23) -> Result<Vec<Value>, AlignmentError> {
24 let mut attrs = vec![Value::Null; arity];
25 attrs[slot::product::GLOBAL_ID] = guid(type_name, global_id)?;
26 if let Some(name) = name {
27 attrs[slot::product::NAME] = Value::Text(name.into());
28 }
29 Ok(attrs)
30}
31
32pub fn alignment(
38 tx: &mut Transaction,
39 global_id: &str,
40 name: Option<&str>,
41 predefined_type: Option<&'static str>,
42) -> Result<EntityId, AlignmentError> {
43 let mut attrs = product_attrs("IFCALIGNMENT", slot::alignment::ARITY, global_id, name)?;
44 if let Some(token) = predefined_type {
45 attrs[slot::alignment::PREDEFINED_TYPE] = Value::Enum(token.into());
46 }
47 Ok(tx.create(Entity::new("IFCALIGNMENT", attrs)))
48}
49
50pub fn horizontal_layout(
56 tx: &mut Transaction,
57 global_id: &str,
58 name: Option<&str>,
59) -> Result<EntityId, AlignmentError> {
60 let attrs = product_attrs(
61 "IFCALIGNMENTHORIZONTAL",
62 slot::product::ARITY,
63 global_id,
64 name,
65 )?;
66 Ok(tx.create(Entity::new("IFCALIGNMENTHORIZONTAL", attrs)))
67}
68
69pub fn vertical_layout(
75 tx: &mut Transaction,
76 global_id: &str,
77 name: Option<&str>,
78) -> Result<EntityId, AlignmentError> {
79 let attrs = product_attrs(
80 "IFCALIGNMENTVERTICAL",
81 slot::product::ARITY,
82 global_id,
83 name,
84 )?;
85 Ok(tx.create(Entity::new("IFCALIGNMENTVERTICAL", attrs)))
86}
87
88pub fn cant_layout(
99 tx: &mut Transaction,
100 global_id: &str,
101 name: Option<&str>,
102 rail_head_distance: f64,
103) -> Result<EntityId, AlignmentError> {
104 finite("IFCALIGNMENTCANT", "RailHeadDistance", rail_head_distance)?;
105 if rail_head_distance <= 0.0 {
106 return Err(invalid(
107 "IFCALIGNMENTCANT",
108 "RailHeadDistance",
109 "the distance between rail heads must be positive",
110 ));
111 }
112 let mut attrs = product_attrs(
113 "IFCALIGNMENTCANT",
114 slot::cant_layout::ARITY,
115 global_id,
116 name,
117 )?;
118 attrs[slot::cant_layout::RAIL_HEAD_DISTANCE] = Value::Real(rail_head_distance);
119 Ok(tx.create(Entity::new("IFCALIGNMENTCANT", attrs)))
120}
121
122pub fn alignment_segment(
133 tx: &mut Transaction,
134 global_id: &str,
135 design_parameters: EntityId,
136) -> Result<EntityId, AlignmentError> {
137 let mut attrs = product_attrs("IFCALIGNMENTSEGMENT", slot::segment::ARITY, global_id, None)?;
138 attrs[slot::segment::DESIGN_PARAMETERS] = Value::Ref(design_parameters);
139 Ok(tx.create(Entity::new("IFCALIGNMENTSEGMENT", attrs)))
140}