Skip to main content

zerodds_corba_giop/
version.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! GIOP Version (Spec §15.4.1).
5
6/// GIOP-Version (`octet major; octet minor`).
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
8pub struct Version {
9    /// Major-Version (typisch `1`).
10    pub major: u8,
11    /// Minor-Version (`0`, `1`, `2`).
12    pub minor: u8,
13}
14
15impl Version {
16    /// GIOP 1.0 — Spec §15.4.1.
17    pub const V1_0: Self = Self { major: 1, minor: 0 };
18    /// GIOP 1.1 — Spec §15.4.1.
19    pub const V1_1: Self = Self { major: 1, minor: 1 };
20    /// GIOP 1.2 — Spec §15.4.1.
21    pub const V1_2: Self = Self { major: 1, minor: 2 };
22
23    /// Konstruktor.
24    #[must_use]
25    pub const fn new(major: u8, minor: u8) -> Self {
26        Self { major, minor }
27    }
28
29    /// `true` wenn die Version Fragment-Messages unterstuetzt
30    /// (Spec §15.4.9: ab GIOP 1.1; in 1.1 nur Request+Reply, in 1.2
31    /// alle Messages).
32    #[must_use]
33    pub const fn supports_fragments(self) -> bool {
34        self.is_at_least(1, 1)
35    }
36
37    /// `true` wenn Fragment-Messages fuer **alle** Message-Types
38    /// erlaubt sind (Spec §15.4.9: ab GIOP 1.2).
39    #[must_use]
40    pub const fn supports_universal_fragments(self) -> bool {
41        self.is_at_least(1, 2)
42    }
43
44    /// `true` wenn das `flags`-Octet (statt `byte_order`) im Header
45    /// steht (Spec §15.4.1: ab GIOP 1.1).
46    #[must_use]
47    pub const fn uses_flags_octet(self) -> bool {
48        self.is_at_least(1, 1)
49    }
50
51    /// `true` wenn der Request/Reply-Header das GIOP-1.2-Layout
52    /// nutzt (`request_id` zuerst, `service_context` zuletzt,
53    /// `TargetAddress` statt `object_key`).
54    #[must_use]
55    pub const fn uses_v1_2_request_layout(self) -> bool {
56        self.is_at_least(1, 2)
57    }
58
59    /// `true` wenn Bidirectional-GIOP unterstuetzt ist (Spec §15.9:
60    /// ab GIOP 1.2 mit `BiDirIIOPServiceContext`).
61    #[must_use]
62    pub const fn supports_bidirectional(self) -> bool {
63        self.is_at_least(1, 2)
64    }
65
66    /// const-fn-faehiger Versions-Vergleich.
67    #[must_use]
68    pub const fn is_at_least(self, major: u8, minor: u8) -> bool {
69        if self.major > major {
70            true
71        } else if self.major == major {
72            self.minor >= minor
73        } else {
74            false
75        }
76    }
77}
78
79#[cfg(test)]
80#[allow(clippy::expect_used, clippy::unwrap_used, clippy::panic)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn version_constants_match_spec() {
86        assert_eq!(Version::V1_0, Version::new(1, 0));
87        assert_eq!(Version::V1_1, Version::new(1, 1));
88        assert_eq!(Version::V1_2, Version::new(1, 2));
89    }
90
91    #[test]
92    fn fragment_support_starts_at_1_1() {
93        assert!(!Version::V1_0.supports_fragments());
94        assert!(Version::V1_1.supports_fragments());
95        assert!(Version::V1_2.supports_fragments());
96    }
97
98    #[test]
99    fn universal_fragments_only_in_1_2() {
100        assert!(!Version::V1_0.supports_universal_fragments());
101        assert!(!Version::V1_1.supports_universal_fragments());
102        assert!(Version::V1_2.supports_universal_fragments());
103    }
104
105    #[test]
106    fn flags_octet_replaces_byte_order_at_1_1() {
107        assert!(!Version::V1_0.uses_flags_octet());
108        assert!(Version::V1_1.uses_flags_octet());
109        assert!(Version::V1_2.uses_flags_octet());
110    }
111
112    #[test]
113    fn v1_2_request_layout_only_in_1_2_plus() {
114        assert!(!Version::V1_0.uses_v1_2_request_layout());
115        assert!(!Version::V1_1.uses_v1_2_request_layout());
116        assert!(Version::V1_2.uses_v1_2_request_layout());
117    }
118
119    #[test]
120    fn bidirectional_starts_at_1_2() {
121        assert!(!Version::V1_0.supports_bidirectional());
122        assert!(!Version::V1_1.supports_bidirectional());
123        assert!(Version::V1_2.supports_bidirectional());
124    }
125
126    #[test]
127    fn version_ordering_works() {
128        assert!(Version::V1_0 < Version::V1_1);
129        assert!(Version::V1_1 < Version::V1_2);
130    }
131}