Skip to main content

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}