Skip to main content

memlink_runtime/
abi.rs

1//! Module ABI version checking and compatibility validation.
2
3pub const MEMLINK_ABI_VERSION: u32 = 1;
4pub const MIN_SUPPORTED_ABI_VERSION: u32 = 1;
5pub const MAX_SUPPORTED_ABI_VERSION: u32 = 1;
6
7#[repr(C)]
8#[derive(Debug, Clone, Copy, Default)]
9pub struct AbiInfo {
10    pub version: u32,
11    pub flags: u32,
12}
13
14impl AbiInfo {
15    pub fn new() -> Self {
16        AbiInfo {
17            version: MEMLINK_ABI_VERSION,
18            flags: 0,
19        }
20    }
21
22    pub fn with_version_and_flags(version: u32, flags: u32) -> Self {
23        AbiInfo { version, flags }
24    }
25
26    pub fn is_compatible(&self) -> bool {
27        self.version >= MIN_SUPPORTED_ABI_VERSION && self.version <= MAX_SUPPORTED_ABI_VERSION
28    }
29
30    pub fn supports_state_serialization(&self) -> bool {
31        self.flags & 0x01 != 0
32    }
33
34    pub fn supports_async(&self) -> bool {
35        self.flags & 0x02 != 0
36    }
37
38    pub fn mismatch_severity(&self) -> AbiMismatchSeverity {
39        if self.is_compatible() {
40            AbiMismatchSeverity::Compatible
41        } else if self.version < MIN_SUPPORTED_ABI_VERSION {
42            AbiMismatchSeverity::TooOld
43        } else {
44            AbiMismatchSeverity::TooNew
45        }
46    }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum AbiMismatchSeverity {
51    Compatible,
52    TooOld,
53    TooNew,
54}
55
56pub fn validate_abi_version(module_version: u32) -> Result<(), AbiVersionError> {
57    if module_version >= MIN_SUPPORTED_ABI_VERSION && module_version <= MAX_SUPPORTED_ABI_VERSION {
58        Ok(())
59    } else if module_version < MIN_SUPPORTED_ABI_VERSION {
60        Err(AbiVersionError::TooOld {
61            module: module_version,
62            min_supported: MIN_SUPPORTED_ABI_VERSION,
63        })
64    } else {
65        Err(AbiVersionError::TooNew {
66            module: module_version,
67            max_supported: MAX_SUPPORTED_ABI_VERSION,
68        })
69    }
70}
71
72#[derive(Debug, Clone, thiserror::Error)]
73pub enum AbiVersionError {
74    #[error("Module ABI version {module} is too old (minimum supported: {min_supported})")]
75    TooOld {
76        module: u32,
77        min_supported: u32,
78    },
79
80    #[error("Module ABI version {module} is too new (maximum supported: {max_supported})")]
81    TooNew {
82        module: u32,
83        max_supported: u32,
84    },
85}