Skip to main content

AirLibrary/Plugins/
ApiVersion.rs

1#![allow(unused_variables, dead_code, unused_imports)]
2
3//! API version compatibility management for the plugin system.
4//!
5//! `ApiVersion` represents a semver triple with an optional pre-release tag.
6//! Compatibility follows the semver major-version rule: plugins with the same
7//! major version and a minor version ≥ the host's are considered compatible.
8//!
9//! `ApiVersionManager` tracks the current host version and the set of
10//! explicitly registered compatible versions.
11
12use serde::{Deserialize, Serialize};
13
14use crate::Result;
15
16/// Semver-style API version.
17#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
18pub struct ApiVersion {
19	pub major:u32,
20	pub minor:u32,
21	pub patch:u32,
22	pub PreRelease:Option<String>,
23}
24
25impl ApiVersion {
26	/// The current host API version.
27	pub fn current() -> Self { Self { major:1, minor:0, patch:0, PreRelease:None } }
28
29	/// Parse from `"major.minor.patch"` or `"major.minor.patch.pre"`.
30	pub fn parse(version:&str) -> Result<Self> {
31		let parts:Vec<&str> = version.split('.').collect();
32		if parts.len() < 3 {
33			return Err(crate::AirError::Plugin("Invalid version format".to_string()));
34		}
35		Ok(Self {
36			major:parts[0]
37				.parse()
38				.map_err(|_| crate::AirError::Plugin("Invalid major version".to_string()))?,
39			minor:parts[1]
40				.parse()
41				.map_err(|_| crate::AirError::Plugin("Invalid minor version".to_string()))?,
42			patch:parts[2]
43				.parse()
44				.map_err(|_| crate::AirError::Plugin("Invalid patch version".to_string()))?,
45			PreRelease:parts.get(3).map(|s| s.to_string()),
46		})
47	}
48
49	/// `true` when `other` is compatible: same major, minor ≥ self.minor.
50	pub fn IsCompatible(&self, other:&ApiVersion) -> bool { self.major == other.major && other.minor >= self.minor }
51}
52
53/// Tracks the current host API version and a set of compatible peer versions.
54pub struct ApiVersionManager {
55	CurrentVersion:ApiVersion,
56	CompatibleVersions:Vec<ApiVersion>,
57}
58
59impl ApiVersionManager {
60	pub fn new() -> Self {
61		let current = ApiVersion::current();
62		Self { CompatibleVersions:vec![current.clone()], CurrentVersion:current }
63	}
64
65	pub fn current(&self) -> &ApiVersion { &self.CurrentVersion }
66
67	pub fn IsCompatible(&self, version:&ApiVersion) -> bool { self.CurrentVersion.IsCompatible(version) }
68
69	/// Register `version` as compatible if it passes the compatibility check.
70	pub fn register_compatible(&mut self, version:ApiVersion) {
71		if self.IsCompatible(&version) && !self.CompatibleVersions.contains(&version) {
72			self.CompatibleVersions.push(version);
73		}
74	}
75}
76
77impl Default for ApiVersionManager {
78	fn default() -> Self { Self::new() }
79}