Skip to main content

ifc_alignment/authoring/
linear.rs

1//! Staging the two linear supertypes.
2//!
3//! Both are concrete despite being supertypes: ONEOF constrains
4//! which subtype an instance may also be, it does not bar writing
5//! the supertype itself. A file states a linear element directly
6//! when it carries no alignment-specific role.
7//!
8//! Neither adds an attribute of its own, so both use the seven
9//! inherited `IfcProduct` slots.
10
11use ifc_model::{Entity, EntityId, Transaction, Value};
12
13use super::guid;
14use crate::error::AlignmentError;
15use crate::slot;
16
17/// Stage an `IfcLinearElement`.
18///
19/// IFC4X3 only: IFC4 does not declare it, and `guid` resolving
20/// against a schema without the entity is the caller's signal.
21///
22/// # Errors
23///
24/// Refuses a `GlobalId` that is not 22 characters.
25pub fn linear_element(
26    tx: &mut Transaction,
27    global_id: &str,
28    name: Option<&str>,
29    placement: Option<EntityId>,
30) -> Result<EntityId, AlignmentError> {
31    const ENTITY: &str = "IFCLINEARELEMENT";
32    let mut attrs = vec![Value::Null; slot::product::ARITY];
33    attrs[slot::product::GLOBAL_ID] = guid(ENTITY, global_id)?;
34    if let Some(name) = name {
35        attrs[slot::product::NAME] = Value::Text(name.into());
36    }
37    if let Some(placement) = placement {
38        attrs[slot::product::OBJECT_PLACEMENT] = Value::Ref(placement);
39    }
40    Ok(tx.create(Entity::new(ENTITY, attrs)))
41}
42
43/// Stage an `IfcLinearPositioningElement`.
44///
45/// `IfcPositioningElement.HasPlacement` makes the placement
46/// required even though the slot is declared OPTIONAL: a
47/// positioning element that positions nothing is the one thing
48/// this entity cannot be. The sibling `linear_element` has no
49/// such rule, which is why the two cannot share a path.
50///
51/// IFC4X3 only.
52///
53/// # Errors
54///
55/// Refuses a `GlobalId` that is not 22 characters, and refuses an
56/// absent `placement`.
57pub fn linear_positioning_element(
58    tx: &mut Transaction,
59    global_id: &str,
60    name: Option<&str>,
61    placement: EntityId,
62) -> Result<EntityId, AlignmentError> {
63    const ENTITY: &str = "IFCLINEARPOSITIONINGELEMENT";
64    let mut attrs = vec![Value::Null; slot::product::ARITY];
65    attrs[slot::product::GLOBAL_ID] = guid(ENTITY, global_id)?;
66    if let Some(name) = name {
67        attrs[slot::product::NAME] = Value::Text(name.into());
68    }
69    attrs[slot::product::OBJECT_PLACEMENT] = Value::Ref(placement);
70    Ok(tx.create(Entity::new(ENTITY, attrs)))
71}