ifc_style/colour/
select.rs1use ifc_model::{EntityId, Value};
4
5use crate::error::{StyleError, StyleResult};
6use crate::view::Record;
7
8#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum ColourOrFactor {
11 Colour(EntityId),
13 Factor(f64),
16}
17
18pub(crate) fn optional_colour_or_factor(
22 record: &Record<'_, '_>,
23 attribute: &'static str,
24) -> StyleResult<Option<ColourOrFactor>> {
25 let Some(value) = record.optional_raw(attribute)? else {
26 return Ok(None);
27 };
28 match value.unwrap_typed() {
29 Value::Ref(target) => {
30 record.check_reference_select(
31 *target,
32 "IfcColour",
33 &["IfcColourSpecification", "IfcPreDefinedColour"],
34 )?;
35 Ok(Some(ColourOrFactor::Colour(*target)))
36 }
37 Value::Real(factor) if factor.is_finite() && (0.0..=1.0).contains(factor) => {
38 Ok(Some(ColourOrFactor::Factor(*factor)))
39 }
40 Value::Integer(factor) if (0..=1).contains(factor) => {
41 Ok(Some(ColourOrFactor::Factor(*factor as f64)))
42 }
43 value => Err(StyleError::InvalidValue {
44 entity: record.entity.type_name.to_string(),
45 id: record.id,
46 attribute,
47 value: format!("{value:?}"),
48 }),
49 }
50}