1use core::marker::PhantomData;
2
3use crate::{Class, DynamicObjectBase};
4
5const fn equal(a: &str, b: &str) -> bool {
6 let a = a.as_bytes();
7 let b = b.as_bytes();
8
9 let mut i = 0;
10 if a.len() != b.len() {
11 return false;
12 }
13 while i < a.len() {
14 if a[i] != b[i] {
15 return false;
16 }
17 i += 1;
18 }
19 true
20}
21
22pub trait ConditionalTrait {
23 type Type;
24}
25
26pub struct ConditionalTImpl<const CONDITION: bool, TrueT, FalseT> {
27 true_t: PhantomData<TrueT>,
28 false_t: PhantomData<FalseT>
29}
30
31impl<TrueT, FalseT> ConditionalTrait for ConditionalTImpl<true, TrueT, FalseT> {
32 type Type = TrueT;
33}
34
35impl<TrueT, FalseT> ConditionalTrait for ConditionalTImpl<false, TrueT, FalseT> {
36 type Type = FalseT;
37}
38
39impl<const CONDITION: bool, TrueT, FalseT> ConditionalTImpl<CONDITION, TrueT, FalseT> {
40 pub const VALUE: bool = CONDITION;
41}
42
43pub type ConditionalT<const VALUE: bool, TrueT, FalseT> =
44 <ConditionalTImpl<VALUE, TrueT, FalseT> as ConditionalTrait>::Type;
45
46pub struct IsSameClass<A: Class, B: Class> {
47 _marker1: PhantomData<A>,
48 _marker2: PhantomData<B>
49}
50
51impl<A: Class, B: Class> IsSameClass<A, B> {
52 pub const VALUE: bool = equal(A::NAME, B::NAME);
53}
54
55pub const fn isSubclassOf<Child: Class, Parent: Class>() -> bool {
56 if IsSameClass::<Child, Parent>::VALUE {
57 return true
58 }
59 else if IsSameClass::<Child, DynamicObjectBase>::VALUE {
60 false
61 }
62 else {
63 isSubclassOf::<Child::Parent, Parent>()
64 }
65}
66
67pub fn offsetOf<Parent: Class, Child: Class>() -> isize {
68 let mut offset = Child::offset();
69 if !IsSameClass::<Parent, Child>::VALUE {
70 offset += offsetOf::<Parent, Child::Parent>();
71 }
72 offset
73}
74
75#[cfg(test)]
76mod test {
77 #![allow(unused_imports)]
78 use dynamic_object_derive::subclass;
79 use crate::{self as dynamic_object, isSubclassOf};
80 use crate::{IsSameClass, DynamicObjectBase};
81 extern crate std;
82 use std::println;
83
84 #[subclass(DynamicObjectBase)]
85 struct MyClass {
86
87 }
88
89 #[test]
90 fn isSameClass() {
91 assert!(IsSameClass::<DynamicObjectBase, DynamicObjectBase>::VALUE);
92 assert!(!IsSameClass::<MyClass, DynamicObjectBase>::VALUE);
93 assert!(IsSameClass::<MyClass, MyClass>::VALUE);
94 }
95
96 #[test]
97 fn subclassOf() {
98 assert!(isSubclassOf::<MyClass, DynamicObjectBase>());
99 }
100
101 #[test]
102 fn offsetof() {
103 #[repr(C)]
104 struct A {
105 value: u32,
106 value2: u32
107 }
108 let a = 0 as *mut A;
109 let ptr: *mut u32 = unsafe { &mut ((*a).value2) };
110 let ptr = ptr as usize;
111 assert!(ptr == 4);
112 }
113}