ifc_resource/actor/
person.rs1use ifc_model::EntityId;
4
5use crate::actor::role::ActorRole;
6use crate::error::{ResourceError, ResourceResult};
7use crate::view::Record;
8
9#[derive(Debug, Clone, Copy)]
17pub struct Person<'m, 's> {
18 record: Record<'m, 's>,
19}
20
21impl<'m, 's> Person<'m, 's> {
22 pub(crate) fn from_record(record: Record<'m, 's>) -> ResourceResult<Self> {
23 let person = Self { record };
24 let identification = person.identification()?;
25 let family_name = person.record.optional_text("FamilyName")?;
26 let given_name = person.record.optional_text("GivenName")?;
27 if person.record.is_ifc2x3() {
28 if family_name.is_none() && given_name.is_none() {
29 return Err(ResourceError::SemanticViolation {
30 entity: Some(person.record.id),
31 rule: "IfcPerson.WR1 (IFC2X3) requires FamilyName or GivenName",
32 });
33 }
34 return Ok(person);
35 }
36 if identification.is_none() && family_name.is_none() && given_name.is_none() {
37 return Err(ResourceError::SemanticViolation {
38 entity: Some(person.record.id),
39 rule:
40 "IfcPerson.IdentifiablePerson requires Identification, FamilyName, or GivenName",
41 });
42 }
43 let middle_names = person.record.optional_text_list("MiddleNames", 1)?;
44 if !middle_names.is_empty() && family_name.is_none() && given_name.is_none() {
45 return Err(ResourceError::SemanticViolation {
46 entity: Some(person.record.id),
47 rule: "IfcPerson.ValidSetOfNames requires FamilyName or GivenName with MiddleNames",
48 });
49 }
50 Ok(person)
51 }
52
53 #[must_use]
55 pub fn id(&self) -> EntityId {
56 self.record.id
57 }
58
59 pub fn identification(&self) -> ResourceResult<Option<&'m str>> {
62 if self.record.is_ifc2x3() {
63 self.record.optional_text("Id")
64 } else {
65 self.record.optional_text("Identification")
66 }
67 }
68
69 pub fn family_name(&self) -> ResourceResult<Option<&'m str>> {
71 self.record.optional_text("FamilyName")
72 }
73
74 pub fn given_name(&self) -> ResourceResult<Option<&'m str>> {
76 self.record.optional_text("GivenName")
77 }
78
79 pub fn middle_names(&self) -> ResourceResult<Vec<&'m str>> {
81 self.record.optional_text_list("MiddleNames", 1)
82 }
83
84 pub fn prefix_titles(&self) -> ResourceResult<Vec<&'m str>> {
86 self.record.optional_text_list("PrefixTitles", 1)
87 }
88
89 pub fn suffix_titles(&self) -> ResourceResult<Vec<&'m str>> {
91 self.record.optional_text_list("SuffixTitles", 1)
92 }
93
94 pub fn role_ids(&self) -> ResourceResult<Vec<EntityId>> {
96 self.record.refs("Roles", "IfcActorRole", 1, true, false)
97 }
98
99 pub fn roles(&self) -> ResourceResult<Vec<ActorRole<'m, 's>>> {
101 self.role_ids()?
102 .into_iter()
103 .map(|id| {
104 Record::new(self.record.model, self.record.schema, id, "IfcActorRole")
105 .and_then(ActorRole::from_record)
106 })
107 .collect()
108 }
109
110 pub fn address_ids(&self) -> ResourceResult<Vec<EntityId>> {
112 self.record.refs("Addresses", "IfcAddress", 1, true, false)
113 }
114}