zenoh_plugin_trait/
compatibility.rs1use std::fmt::Display;
16
17use zenoh_result::{bail, ZResult};
18
19pub trait StructVersion {
20 fn struct_version() -> &'static str;
22 fn struct_features() -> &'static str;
26}
27
28#[repr(C)]
29#[derive(Debug, Clone)]
30pub struct Compatibility {
31 rust_version: RustVersion,
32 zenoh_version: stabby::str::Str<'static>,
33 zenoh_features: stabby::str::Str<'static>,
34}
35
36impl Compatibility {
37 pub fn new(zenoh_version: &'static str, zenoh_features: &'static str) -> Self {
38 let rust_version = RustVersion::new();
39 Self {
40 rust_version,
41 zenoh_version: zenoh_version.into(),
42 zenoh_features: zenoh_features.into(),
43 }
44 }
45
46 pub fn check(&self, other: &Self) -> ZResult<()> {
47 fn get_version_and_commit(version: &str) -> (&str, &str) {
48 let parts = version.split('-').collect::<Vec<_>>();
49 (
50 parts.first().cloned().unwrap_or("undefined"),
51 parts.get(1).cloned().unwrap_or("undefined"),
52 )
53 }
54
55 fn version_equals(left: &str, right: &str) -> bool {
56 const RELEASE_COMMIT: &str = "release"; let (left_version, left_commit) = get_version_and_commit(left);
58 let (right_version, right_commit) = get_version_and_commit(right);
59 if left_version != right_version {
60 return false;
61 }
62 if left_commit != right_commit
69 && left_commit != RELEASE_COMMIT
70 && right_commit != RELEASE_COMMIT
71 {
72 return false;
73 }
74 true
75 }
76
77 if self.rust_version != other.rust_version {
78 bail!(
79 "Incompatible rustc versions:\n host: {}\n plugin: {}",
80 self.rust_version,
81 other.rust_version
82 )
83 } else if !version_equals(&self.zenoh_version, &other.zenoh_version) {
84 bail!(
85 "Incompatible Zenoh versions:\n host: {}\n plugin: {}",
86 self.zenoh_version,
87 other.zenoh_version
88 )
89 } else if self.zenoh_features != other.zenoh_features {
90 bail!(
91 "Incompatible Zenoh feature sets:\n host: {}\n plugin: {}",
92 self.zenoh_features,
93 other.zenoh_features
94 )
95 } else {
96 Ok(())
97 }
98 }
99}
100
101impl Display for Compatibility {
102 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103 writeln!(f, "Rust version:\n{}", self.rust_version)?;
104 writeln!(f, "Zenoh version:\n {}", &self.zenoh_version)?;
105 writeln!(f, "Zenoh features:\n {}", &self.zenoh_features)?;
106 Ok(())
107 }
108}
109
110#[repr(C)]
111#[derive(Debug, PartialEq, Eq, Clone)]
112pub struct RustVersion {
113 major: u32,
114 minor: u32,
115 patch: u32,
116 stable: bool,
117 commit: stabby::str::Str<'static>,
118}
119
120impl Display for RustVersion {
121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122 write!(
123 f,
124 "Rust {}.{}.{}{} commit {}",
125 self.major,
126 self.minor,
127 self.patch,
128 if self.stable { "" } else { "-nightly" },
129 self.commit
130 )
131 }
132}
133
134const RELEASE_AND_COMMIT: (&str, &str) = zenoh_macros::rustc_version_release!();
135impl RustVersion {
136 pub fn new() -> Self {
137 let (release, commit) = RELEASE_AND_COMMIT;
138 let (release, stable) = if let Some(p) = release.chars().position(|c| c == '-') {
139 (&release[..p], false)
140 } else {
141 (release, true)
142 };
143 let mut split = release.split('.').map(|s| s.trim());
144 RustVersion {
145 major: split.next().unwrap().parse().unwrap(),
146 minor: split.next().unwrap().parse().unwrap(),
147 patch: split.next().unwrap().parse().unwrap(),
148 stable,
149 commit: commit.into(),
150 }
151 }
152}
153
154impl Default for RustVersion {
155 fn default() -> Self {
156 Self::new()
157 }
158}