1pub mod context;
2pub mod function;
3pub mod host;
4pub mod meta;
5pub mod object;
6pub mod registry;
7pub mod script;
8pub mod transformer;
9pub mod types;
10pub mod utils;
11
12pub use memoffset::offset_of as __internal__offset_of__;
13
14#[macro_export]
16macro_rules! __internal__offset_of_enum__ {
17 ($type:tt :: $variant:ident [ $( $field:ident ),* ] => $used_field:ident => $discriminant:literal) => {{
18 let mut data = std::mem::MaybeUninit::<$type>::uninit();
19 let ptr = data.as_mut_ptr().cast::<u8>();
20 #[allow(clippy::macro_metavars_in_unsafe)]
21 unsafe {
22 ptr.write($discriminant);
23 #[allow(unused_variables)]
24 match data.assume_init_ref() {
25 $type::$variant( $( $field ),* ) => {
26 ($used_field as *const _ as *const u8).offset_from(ptr) as usize
27 }
28 _ => unreachable!(),
29 }
30 }
31 }};
32 ($type:tt :: $variant:ident ( $index:tt ) => $discriminant:literal) => {{
33 let mut data = std::mem::MaybeUninit::<$type>::uninit();
34 let ptr = data.as_mut_ptr().cast::<u8>();
35 #[allow(clippy::macro_metavars_in_unsafe)]
36 unsafe {
37 ptr.write($discriminant);
38 #[allow(unused_variables)]
39 match data.assume_init_ref() {
40 $type::$variant {
41 $index: __value__, ..
42 } => (__value__ as *const _ as *const u8).offset_from(ptr) as usize,
43 _ => unreachable!(),
44 }
45 }
46 }};
47 ($type:tt :: $variant:ident { $field:ident } => $discriminant:literal) => {{
48 let mut data = std::mem::MaybeUninit::<$type>::uninit();
49 let ptr = data.as_mut_ptr().cast::<u8>();
50 #[allow(clippy::macro_metavars_in_unsafe)]
51 unsafe {
52 ptr.write($discriminant);
53 #[allow(unused_variables)]
54 match data.assume_init_ref() {
55 $type::$variant { $field, .. } => {
56 ($field as *const _ as *const u8).offset_from(ptr) as usize
57 }
58 _ => unreachable!(),
59 }
60 }
61 }};
62}
63
64pub mod prelude {
65 pub use crate::{
66 IntuicioEnum, IntuicioStruct, IntuicioVersion, Visibility,
67 context::*,
68 function::*,
69 host::*,
70 object::*,
71 registry::*,
72 script::*,
73 transformer::*,
74 types::{enum_type::*, struct_type::*, *},
75 };
76 pub use crate::{
77 define_function, define_native_enum, define_native_struct, define_runtime_enum,
78 define_runtime_struct, function_signature,
79 };
80}
81
82use crate::{
83 registry::Registry,
84 types::{enum_type::Enum, struct_type::Struct},
85};
86use serde::{Deserialize, Serialize};
87
88#[derive(
89 Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
90)]
91pub enum Visibility {
92 Private,
93 Module,
94 #[default]
95 Public,
96}
97
98impl Visibility {
99 pub fn is_visible(self, scope: Self) -> bool {
100 self >= scope
101 }
102
103 pub fn is_public(&self) -> bool {
104 *self == Visibility::Public
105 }
106
107 pub fn is_module(&self) -> bool {
108 *self == Visibility::Module
109 }
110
111 pub fn is_private(&self) -> bool {
112 *self == Visibility::Private
113 }
114}
115
116pub trait IntuicioStruct {
117 fn define_struct(registry: &Registry) -> Struct;
118}
119
120pub trait IntuicioEnum {
121 fn define_enum(registry: &Registry) -> Enum;
122}
123
124#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
125#[repr(C)]
126pub struct IntuicioVersion {
127 major: usize,
128 minor: usize,
129 patch: usize,
130}
131
132impl IntuicioVersion {
133 pub fn new(major: usize, minor: usize, patch: usize) -> Self {
134 Self {
135 major,
136 minor,
137 patch,
138 }
139 }
140
141 pub fn major(&self) -> usize {
142 self.major
143 }
144
145 pub fn minor(&self) -> usize {
146 self.minor
147 }
148
149 pub fn patch(&self) -> usize {
150 self.patch
151 }
152
153 pub fn is_compatible(&self, other: &Self) -> bool {
154 self.major == other.major && self.minor == other.minor
155 }
156}
157
158impl std::fmt::Display for IntuicioVersion {
159 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
161 }
162}
163
164impl std::fmt::Debug for IntuicioVersion {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 f.debug_struct("IntuicioVersion")
167 .field("major", &self.major)
168 .field("minor", &self.minor)
169 .field("patch", &self.patch)
170 .finish()
171 }
172}
173
174#[macro_export]
175macro_rules! crate_version {
176 () => {{
177 let major = env!("CARGO_PKG_VERSION_MAJOR", "0")
178 .parse::<usize>()
179 .unwrap();
180 let minor = env!("CARGO_PKG_VERSION_MINOR", "0")
181 .parse::<usize>()
182 .unwrap();
183 let patch = env!("CARGO_PKG_VERSION_PATCH", "0")
184 .parse::<usize>()
185 .unwrap();
186 $crate::IntuicioVersion::new(major, minor, patch)
187 }};
188}
189
190pub fn core_version() -> IntuicioVersion {
191 crate_version!()
192}
193
194#[cfg(test)]
195mod tests {
196 use crate::Visibility;
197
198 #[test]
199 fn test_visibility() {
200 assert!(Visibility::Private.is_visible(Visibility::Private));
201 assert!(!Visibility::Private.is_visible(Visibility::Module));
202 assert!(!Visibility::Private.is_visible(Visibility::Public));
203 assert!(Visibility::Module.is_visible(Visibility::Private));
204 assert!(Visibility::Module.is_visible(Visibility::Module));
205 assert!(!Visibility::Module.is_visible(Visibility::Public));
206 assert!(Visibility::Public.is_visible(Visibility::Private));
207 assert!(Visibility::Public.is_visible(Visibility::Module));
208 assert!(Visibility::Public.is_visible(Visibility::Public));
209 }
210
211 #[test]
212 fn test_offset_of_enum() {
213 #[allow(dead_code)]
214 #[repr(u8)]
215 enum Foo {
216 A,
217 B(usize),
218 C(u8, u16),
219 D { a: u32, b: u64 },
220 }
221
222 assert_eq!(__internal__offset_of_enum__!(Foo::B[v] => v => 1), 8);
223 assert_eq!(__internal__offset_of_enum__!(Foo::B(0) => 1), 8);
224 assert_eq!(__internal__offset_of_enum__!(Foo::C[a, b] => a => 2), 1);
225 assert_eq!(__internal__offset_of_enum__!(Foo::C[a, b] => b => 2), 2);
226 assert_eq!(__internal__offset_of_enum__!(Foo::C(0) => 2), 1);
227 assert_eq!(__internal__offset_of_enum__!(Foo::C(1) => 2), 2);
228 assert_eq!(__internal__offset_of_enum__!(Foo::D { a } => 3), 4);
229 assert_eq!(__internal__offset_of_enum__!(Foo::D { b } => 3), 8);
230 }
231}