meowtonin_byondapi_sys/
lib.rs

1// SPDX-License-Identifier: 0BSD
2#![allow(
3	non_upper_case_globals,
4	non_camel_case_types,
5	non_snake_case,
6	clippy::missing_safety_doc
7)]
8
9#[allow(warnings, clippy::all)]
10#[rustfmt::skip]
11pub mod bindings;
12mod version;
13
14#[cfg(doc)]
15pub use bindings::ByondApi as RawByondApi;
16
17// According to acrimon, in theory slightly faster...
18#[cfg_attr(target_pointer_width = "32", repr(align(64)))]
19#[cfg_attr(target_pointer_width = "64", repr(align(128)))]
20pub struct ByondApi {
21	internal: bindings::ByondApi,
22	version: ByondVersion,
23}
24
25unsafe impl Sync for ByondApi {}
26unsafe impl Send for ByondApi {}
27
28impl ByondApi {
29	/// Initialize [ByondApi], using the given library.
30	pub unsafe fn init_from_library<Lib>(library: Lib) -> Result<ByondApi, libloading::Error>
31	where
32		Lib: Into<libloading::Library>,
33	{
34		let lib = library.into();
35		let version = unsafe { version::get_byond_version(&lib) };
36		let internal = unsafe { bindings::ByondApi::from_library(lib) }?;
37		Ok(ByondApi { internal, version })
38	}
39
40	/// Get the version of the ByondApi library.
41	#[must_use]
42	pub fn get_version(&self) -> ByondVersion {
43		self.version
44	}
45}
46
47impl std::ops::Deref for ByondApi {
48	type Target = bindings::ByondApi;
49
50	fn deref(&self) -> &Self::Target {
51		&self.internal
52	}
53}
54
55pub use crate::version::ByondVersion;
56// Stabilized types
57pub use crate::bindings::{
58	ByondValueData, ByondValueType, CByondPixLoc, CByondValue, CByondXYZ, s1c, s2c, s4c, s8c, u1c,
59	u2c, u4c, u4cOrPointer, u8c,
60};
61
62pub const NONE: u2c = u2c::MAX;
63pub const NOCH: u1c = u1c::MAX;
64
65cfg_if::cfg_if! {
66	if #[cfg(feature = "bytemuck")] {
67		unsafe impl bytemuck::Zeroable for ByondValueData {}
68		unsafe impl bytemuck::Pod for ByondValueData {}
69
70		unsafe impl bytemuck::Zeroable for CByondValue {}
71		unsafe impl bytemuck::Pod for CByondValue {}
72
73		unsafe impl bytemuck::Zeroable for CByondXYZ {}
74		unsafe impl bytemuck::Pod for CByondXYZ {}
75	}
76}
77
78#[cfg(test)]
79mod tests {
80	#[test]
81	fn ensure_typedefs_match() {
82		use crate::bindings::{s1c, s2c, s4c, s8c, u1c, u2c, u4c, u8c};
83		use std::mem::size_of;
84
85		assert_eq!(size_of::<u1c>(), size_of::<u8>(), "u1c != u8");
86		assert_eq!(size_of::<s1c>(), size_of::<i8>(), "s1c != i8");
87
88		assert_eq!(size_of::<u2c>(), size_of::<u16>(), "u2c != u16");
89		assert_eq!(size_of::<s2c>(), size_of::<i16>(), "s2c != i16");
90
91		assert_eq!(size_of::<u4c>(), size_of::<u32>(), "u4c != u32");
92		assert_eq!(size_of::<s4c>(), size_of::<i32>(), "s4c != i32");
93
94		assert_eq!(size_of::<u8c>(), size_of::<u64>(), "u8c != u64");
95		assert_eq!(size_of::<s8c>(), size_of::<i64>(), "s8c != i64");
96	}
97}