openbim_ids/lib.rs
1//! `openbim-ids` — buildingSMART Information Delivery Specification.
2//!
3//! # What this is
4//!
5//! The standard, machine-readable way to state *"this model must contain these
6//! things, with these properties"* and audit a model against it. It is the
7//! highest-leverage openBIM standard for real projects, because it turns
8//! contractual information requirements into an automated check.
9//!
10//! # 🚨 One namespace, six schema versions
11//!
12//! Every published IDS version from 0.2 to 1.0 declares the **same**
13//! `targetNamespace`. The namespace identifies the format, never the version.
14//! Because the differences are in attribute *names* and cardinality rather
15//! than element names, a reader that guesses wrong does not fail — it silently
16//! produces a *different* specification.
17//!
18//! Version detection must therefore report how it knows, and must surface
19//! disagreement between a file's claim and its shape instead of picking one.
20//! `openbim_core::Detected` exists for exactly this.
21//!
22//! Only 1.0 is an approved buildingSMART standard. Older versions are worth
23//! *reading* because files using them exist; new documents should be 1.0.
24//!
25//! # Reporting discipline
26//!
27//! An audit that quietly treats "property missing" as "check passed" is worse
28//! than no audit. Results distinguish applicable-and-passed,
29//! applicable-and-failed, and not-applicable — see `openbim_core::Outcome`.
30//!
31//! # Why this is not in `packages/`
32//!
33//! IDS is a *consumer* of the IFC layer, not part of it. Nothing in
34//! `packages/` may depend on it. That one-way rule is what stops the IFC
35//! core from accreting every standard that happens to use it.
36//!
37//! # Status
38//!
39//! **Reserved — no implementation.** Published to establish the name.
40//!
41//! An oracle already exists on disk: the buildingSMART IDS test corpus carries
42//! `pass-`/`fail-` cases, so the acceptance bar for the implementation is that
43//! every `pass-` case passes and every `fail-` case fails, with not-applicable
44//! distinguished from passed.
45
46#![forbid(unsafe_code)]
47
48/// The XML namespace shared by **all** IDS versions.
49///
50/// Deliberately a single constant: there is no per-version namespace to key
51/// on, which is the whole difficulty of reading IDS.
52pub const NAMESPACE: &str = "http://standards.buildingsmart.org/IDS";
53
54/// A published IDS schema version.
55///
56/// Ordered oldest to newest; `Ids1_0` is the only approved standard.
57#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub enum IdsVersion {
59 /// 0.9 and earlier pre-release drafts.
60 Draft0_9,
61 /// 0.9.6.
62 Draft0_9_6,
63 /// 0.9.7.
64 Draft0_9_7,
65 /// 1.0 — the approved buildingSMART standard.
66 Ids1_0,
67}
68
69impl IdsVersion {
70 /// The version new documents should be written as.
71 ///
72 /// Writing anything older is a deliberate compatibility choice, never a
73 /// default.
74 pub const CURRENT: IdsVersion = IdsVersion::Ids1_0;
75
76 /// Whether this version is an approved standard rather than a draft.
77 #[must_use]
78 pub fn is_approved(self) -> bool {
79 matches!(self, IdsVersion::Ids1_0)
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn only_1_0_is_approved() {
89 assert!(IdsVersion::Ids1_0.is_approved());
90 assert!(!IdsVersion::Draft0_9.is_approved());
91 assert!(!IdsVersion::Draft0_9_6.is_approved());
92 assert!(!IdsVersion::Draft0_9_7.is_approved());
93 }
94
95 #[test]
96 fn current_is_the_newest_version() {
97 assert_eq!(IdsVersion::CURRENT, IdsVersion::Ids1_0);
98 assert!(IdsVersion::Ids1_0 > IdsVersion::Draft0_9_7);
99 assert!(IdsVersion::Draft0_9_7 > IdsVersion::Draft0_9);
100 }
101}