Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions crates/ogar-vocab/src/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,29 @@ pub trait PortSpec: 'static + Send + Sync {
/// (`APP-CLASS-CODEBOOK-LAYOUT.md` §2; the prefix VALUES are
/// order-invariant).
///
/// # Position in the `domain : appid : classview` spelling
///
/// Per `DISCOVERY-MAP.md` D-CLASSID-HI-U16-SPELLING the composed
/// classid u32 reads **`domain(2 nibbles) : appid(2 nibbles) :
/// classview(4 nibbles)`** — i.e. `0xDDCCVVVV`, where the hi u16
/// `0xDDCC` (`domain byte ++ appid byte`) is the shared CANON concept
/// and the lo u16 `0xVVVV` is the per-vendor render skin. **`APP_PREFIX`
/// IS that lo-u16 `classview` slot** — see [`Self::classview`], the
/// preferred name for it.
///
/// **Homonym warning** (the reason the two names coexist): the word
/// "app" appears in BOTH halves with different meanings. The **appid
/// byte** (hi half) is the shared app-concept slot within a domain
/// (e.g. `0x0102` = project work item, converged on by OpenProject
/// `0x0102_0001` AND Redmine `0x0102_0007`); the **APP render prefix**
/// here (lo half) is the per-vendor ClassView skin. They are
/// positionally distinct registers — `APP_PREFIX` is the *classview*,
/// NOT the appid.
///
/// Composing the full render classid:
/// ```text
/// render_classid = (concept as u32) << 16 | APP_PREFIX
/// // └──── hi u16: domain:appid ────┘ └ lo u16: classview ┘
/// ```
///
/// `0x0000` is the **shared canonical core** — the cross-app ontology
Expand All @@ -78,6 +98,18 @@ pub trait PortSpec: 'static + Send + Sync {
/// data — consumers re-export it instead of hardcoding `0x0001` etc.
const APP_PREFIX: u16 = 0x0000;

/// The **classview** — the memorable name for [`Self::APP_PREFIX`] in
/// the operator's `domain : appid : classview` spelling
/// (D-CLASSID-HI-U16-SPELLING). Identical value; this accessor exists
/// so call sites can read the lo-u16 render-skin slot by the name that
/// matches the canon layout instead of the `APP_PREFIX` homonym. New
/// code should prefer `Port::classview()`; `APP_PREFIX` stays as the
/// underlying const (every existing consumer re-exports it).
#[must_use]
fn classview() -> u16 {
Self::APP_PREFIX
}

/// All `(port-public-name, canonical-class-id)` aliases for this
/// port. Order is not significant for resolution but kept stable
/// for human readability.
Expand Down Expand Up @@ -1070,6 +1102,15 @@ mod tests {
);
assert_eq!(OdooPort::APP_PREFIX, 0x0002, "Odoo prefix must be 0x0002");
assert_eq!(WoaPort::APP_PREFIX, 0x0003, "WoA prefix must be 0x0003");
// `classview()` is the memorable name for the same lo-u16 slot
// (D-CLASSID-HI-U16-SPELLING); it must equal `APP_PREFIX` for every
// port so the two names never drift.
assert_eq!(OpenProjectPort::classview(), OpenProjectPort::APP_PREFIX);
assert_eq!(OdooPort::classview(), OdooPort::APP_PREFIX);
assert_eq!(WoaPort::classview(), WoaPort::APP_PREFIX);
assert_eq!(SmbPort::classview(), SmbPort::APP_PREFIX);
assert_eq!(HealthcarePort::classview(), HealthcarePort::APP_PREFIX);
assert_eq!(RedminePort::classview(), RedminePort::APP_PREFIX);
assert_eq!(
SmbPort::APP_PREFIX,
0x0004,
Expand Down
Loading