ifc_validate/report/
path.rs1use std::fmt;
4
5use ifc_model::EntityId;
6
7#[derive(Debug, Clone, PartialEq, Eq, Hash)]
13#[non_exhaustive]
14pub enum Path {
15 File,
17 Entity(EntityId),
19 Attribute {
21 entity: EntityId,
23 index: usize,
25 name: Option<String>,
27 },
28}
29
30impl fmt::Display for Path {
31 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
32 match self {
33 Self::File => formatter.write_str("<file>"),
34 Self::Entity(id) => write!(formatter, "{id}"),
35 Self::Attribute {
36 entity,
37 index,
38 name,
39 } => match name {
40 Some(name) => write!(formatter, "{entity}.{name}"),
41 None => write!(formatter, "{entity}[{index}]"),
42 },
43 }
44 }
45}
46
47#[must_use]
52pub(crate) fn path_key(path: &Path) -> (u64, usize) {
53 match path {
54 Path::File => (0, 0),
55 Path::Entity(id) => (id.0, 0),
56 Path::Attribute { entity, index, .. } => (entity.0, *index + 1),
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn an_attribute_path_names_the_slot_when_the_schema_does() {
66 let named = Path::Attribute {
67 entity: EntityId(7),
68 index: 2,
69 name: Some("Name".into()),
70 };
71 assert_eq!(named.to_string(), "#7.Name");
72 let anonymous = Path::Attribute {
73 entity: EntityId(7),
74 index: 2,
75 name: None,
76 };
77 assert_eq!(anonymous.to_string(), "#7[2]");
78 }
79
80 #[test]
82 fn the_file_path_sorts_first() {
83 assert!(path_key(&Path::File) < path_key(&Path::Entity(EntityId(1))));
84 }
85}