xmtp_mls_core/version.rs
1use std::sync::Arc;
2
3use xmtp_mls_group_state::libxmtp_version::LibXMTPVersion;
4
5#[derive(Clone, Debug, PartialEq)]
6pub struct VersionInfo {
7 pkg_version: Arc<str>,
8 /// `pkg_version` parsed once at construction. This is the client's own
9 /// build identity, not remote data, so it is always valid semver
10 /// (see [`VersionInfo::new`]) — receive-path guards can compare against
11 /// it without re-parsing the string on every message.
12 pkg_semver: LibXMTPVersion,
13}
14
15impl Default for VersionInfo {
16 fn default() -> Self {
17 Self::new(env!("CARGO_PKG_VERSION"))
18 }
19}
20
21impl VersionInfo {
22 /// Build a `VersionInfo`, parsing and caching the semver form.
23 ///
24 /// `version` is the client's own package version — in production always
25 /// the compile-time `CARGO_PKG_VERSION`. A non-semver value is a build
26 /// or configuration bug, not runtime data, so it panics here rather than
27 /// silently disabling the below-floor pause on every group later.
28 fn new(version: &str) -> Self {
29 let pkg_semver = LibXMTPVersion::parse(version)
30 .unwrap_or_else(|_| panic!("client pkg_version {version:?} is not valid semver"));
31 Self {
32 pkg_version: version.into(),
33 pkg_semver,
34 }
35 }
36
37 pub fn pkg_version(&self) -> &str {
38 &self.pkg_version
39 }
40
41 /// The client's own version, parsed once at construction. Prefer this
42 /// over re-parsing [`pkg_version`](Self::pkg_version) on hot paths.
43 pub fn pkg_semver(&self) -> &LibXMTPVersion {
44 &self.pkg_semver
45 }
46
47 /// Makes this the version of a client a test builds, instead of the
48 /// package version.
49 #[cfg(any(test, feature = "test-hooks"))]
50 pub fn test_update_version(&mut self, version: &str) {
51 *self = Self::new(version);
52 }
53}