dynamic_object/
typing.rs

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}