1use core::fmt;
10
11use crate::sys;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
23pub struct TelemetryApiVersion(u32);
24
25impl TelemetryApiVersion {
26 pub const V1_00: Self = Self(sys::SCS_TELEMETRY_VERSION_1_00);
28
29 pub const V1_01: Self = Self(sys::SCS_TELEMETRY_VERSION_1_01);
31
32 pub const CURRENT: Self = Self(sys::SCS_TELEMETRY_VERSION_CURRENT);
34
35 #[must_use]
37 pub const fn new(major: u32, minor: u32) -> Self {
38 Self(sys::make_version(major, minor))
39 }
40
41 #[must_use]
43 pub const fn from_raw(raw: u32) -> Self {
44 Self(raw)
45 }
46
47 #[must_use]
49 pub const fn raw(self) -> u32 {
50 self.0
51 }
52
53 #[must_use]
55 pub const fn major(self) -> u32 {
56 sys::version_major(self.0)
57 }
58
59 #[must_use]
61 pub const fn minor(self) -> u32 {
62 sys::version_minor(self.0)
63 }
64}
65
66impl fmt::Display for TelemetryApiVersion {
67 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(formatter, "{}.{}", self.major(), self.minor())
69 }
70}
71
72#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
77pub struct InputApiVersion(u32);
78
79impl InputApiVersion {
80 pub const V1_00: Self = Self(sys::SCS_INPUT_VERSION_1_00);
82
83 pub const CURRENT: Self = Self(sys::SCS_INPUT_VERSION_CURRENT);
85
86 #[must_use]
87 pub const fn new(major: u32, minor: u32) -> Self {
88 Self(sys::make_version(major, minor))
89 }
90
91 #[must_use]
92 pub const fn from_raw(raw: u32) -> Self {
93 Self(raw)
94 }
95
96 #[must_use]
97 pub const fn raw(self) -> u32 {
98 self.0
99 }
100
101 #[must_use]
102 pub const fn major(self) -> u32 {
103 sys::version_major(self.0)
104 }
105
106 #[must_use]
107 pub const fn minor(self) -> u32 {
108 sys::version_minor(self.0)
109 }
110}
111
112impl fmt::Display for InputApiVersion {
113 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
114 write!(formatter, "{}.{}", self.major(), self.minor())
115 }
116}
117
118#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
124pub struct InputGameVersion(u32);
125
126impl InputGameVersion {
127 #[must_use]
128 pub const fn new(major: u32, minor: u32) -> Self {
129 Self(sys::make_version(major, minor))
130 }
131
132 #[must_use]
133 pub const fn from_raw(raw: u32) -> Self {
134 Self(raw)
135 }
136
137 #[must_use]
138 pub const fn raw(self) -> u32 {
139 self.0
140 }
141
142 #[must_use]
143 pub const fn major(self) -> u32 {
144 sys::version_major(self.0)
145 }
146
147 #[must_use]
148 pub const fn minor(self) -> u32 {
149 sys::version_minor(self.0)
150 }
151}
152
153impl fmt::Display for InputGameVersion {
154 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
155 write!(formatter, "{}.{}", self.major(), self.minor())
156 }
157}
158
159#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
166pub struct GameSchemaVersion(u32);
167
168impl GameSchemaVersion {
169 #[must_use]
171 pub const fn new(major: u32, minor: u32) -> Self {
172 Self(sys::make_version(major, minor))
173 }
174
175 #[must_use]
177 pub const fn from_raw(raw: u32) -> Self {
178 Self(raw)
179 }
180
181 #[must_use]
183 pub const fn raw(self) -> u32 {
184 self.0
185 }
186
187 #[must_use]
189 pub const fn major(self) -> u32 {
190 sys::version_major(self.0)
191 }
192
193 #[must_use]
195 pub const fn minor(self) -> u32 {
196 sys::version_minor(self.0)
197 }
198}
199
200impl fmt::Display for GameSchemaVersion {
201 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
202 write!(formatter, "{}.{}", self.major(), self.minor())
203 }
204}
205
206#[cfg(test)]
207mod tests {
208 extern crate std;
209
210 use super::*;
211 use std::string::ToString;
212
213 #[test]
214 fn telemetry_api_version_preserves_unknown_values_for_negotiation() {
215 let future = TelemetryApiVersion::new(2, 7);
216
217 assert_eq!(future.major(), 2);
218 assert_eq!(future.minor(), 7);
219 assert_eq!(TelemetryApiVersion::from_raw(future.raw()), future);
220 assert_eq!(future.to_string(), "2.7");
221 }
222
223 #[test]
224 fn game_schema_version_is_not_interchangeable_with_api_version() {
225 let schema = GameSchemaVersion::new(1, 19);
226
227 assert_eq!(schema.major(), 1);
228 assert_eq!(schema.minor(), 19);
229 assert_eq!(GameSchemaVersion::from_raw(schema.raw()), schema);
230 assert_eq!(schema.to_string(), "1.19");
231 }
232
233 #[test]
234 fn input_versions_are_independent_from_telemetry_versions() {
235 assert_eq!(InputApiVersion::CURRENT, InputApiVersion::V1_00);
236 assert_eq!(InputApiVersion::V1_00.raw(), sys::make_version(1, 0));
237 assert_eq!(InputGameVersion::new(1, 0).to_string(), "1.0");
238 }
239}