1use std::{
4 fmt::{self, Debug, Display},
5 marker::PhantomData,
6};
7
8#[allow(unused_imports)]
9use core_extensions::SelfOps;
10
11use super::{c_functions::*, *};
12
13use crate::{
14 marker_type::ErasedObject,
15 pointer_trait::{AsPtr, TransmuteElement},
16 sabi_types::{RMut, RRef},
17 std_types::RBox,
18};
19
20#[repr(C)]
24#[derive(StableAbi)]
25pub struct HasherObject<'a> {
26 this: RMut<'a, ErasedObject>,
27 write_fns: &'static WriteFns,
28 finish: unsafe extern "C" fn(RRef<'_, ErasedObject>) -> u64,
29}
30
31impl<'a> HasherObject<'a> {
32 pub fn new<T: 'a>(this: &'a mut T) -> HasherObject<'a>
34 where
35 T: Hasher,
36 {
37 HasherObject {
38 this: unsafe {
39 this.transmute_element::<ErasedObject>()
41 },
42 write_fns: MakeWriteFns::<T>::V,
43 finish: finish_Hasher::<T>,
44 }
45 }
46
47 pub fn as_mut<'b: 'a>(&'b mut self) -> HasherObject<'b> {
49 Self {
50 this: self.this.reborrow(),
51 write_fns: self.write_fns,
52 finish: self.finish,
53 }
54 }
55}
56
57macro_rules! impl_write {
58 ( $(($ty:ty, $fn:ident)),* ) => {
59 $(
60 fn $fn(&mut self, val: $ty) {
61 unsafe { (self.write_fns.$fn)(self.this.reborrow(), val) }
62 }
63 )*
64 }
65}
66
67impl<'a> Hasher for HasherObject<'a> {
68 fn finish(&self) -> u64 {
69 unsafe { (self.finish)(self.this.as_rref()) }
70 }
71 fn write(&mut self, bytes: &[u8]) {
72 unsafe { (self.write_fns.write)(self.this.reborrow(), bytes.into()) }
73 }
74
75 impl_write!(
76 (i16, write_i16),
77 (i32, write_i32),
78 (i64, write_i64),
79 (i8, write_i8),
80 (isize, write_isize),
81 (u16, write_u16),
82 (u32, write_u32),
83 (u64, write_u64),
84 (u8, write_u8),
85 (usize, write_usize)
86 );
87}
88
89#[repr(C)]
97#[derive(StableAbi)]
98struct WriteFns {
99 write: unsafe extern "C" fn(RMut<'_, ErasedObject>, RSlice<'_, u8>),
100 write_i16: unsafe extern "C" fn(RMut<'_, ErasedObject>, i16),
103 write_i32: unsafe extern "C" fn(RMut<'_, ErasedObject>, i32),
104 write_i64: unsafe extern "C" fn(RMut<'_, ErasedObject>, i64),
105 write_i8: unsafe extern "C" fn(RMut<'_, ErasedObject>, i8),
106 write_isize: unsafe extern "C" fn(RMut<'_, ErasedObject>, isize),
107 write_u16: unsafe extern "C" fn(RMut<'_, ErasedObject>, u16),
110 write_u32: unsafe extern "C" fn(RMut<'_, ErasedObject>, u32),
111 write_u64: unsafe extern "C" fn(RMut<'_, ErasedObject>, u64),
112 write_u8: unsafe extern "C" fn(RMut<'_, ErasedObject>, u8),
113 write_usize: unsafe extern "C" fn(RMut<'_, ErasedObject>, usize),
114}
115
116struct MakeWriteFns<T>(PhantomData<T>);
117
118impl<T: Hasher> MakeWriteFns<T> {
119 const V: &'static WriteFns = &WriteFns {
120 write: write_Hasher::<T>,
121 write_i16: write_i16_Hasher::<T>,
122 write_i32: write_i32_Hasher::<T>,
123 write_i64: write_i64_Hasher::<T>,
124 write_i8: write_i8_Hasher::<T>,
125 write_isize: write_isize_Hasher::<T>,
126 write_u16: write_u16_Hasher::<T>,
127 write_u32: write_u32_Hasher::<T>,
128 write_u64: write_u64_Hasher::<T>,
129 write_u8: write_u8_Hasher::<T>,
130 write_usize: write_usize_Hasher::<T>,
131 };
132}
133
134#[repr(C)]
139#[derive(StableAbi)]
140pub struct DebugDisplayObject {
141 this: RBox<ErasedObject>,
142 display: unsafe extern "C" fn(
143 RRef<'_, ErasedObject>,
144 FormattingMode,
145 &mut RString,
146 ) -> RResult<(), ()>,
147 debug: unsafe extern "C" fn(
148 RRef<'_, ErasedObject>,
149 FormattingMode,
150 &mut RString,
151 ) -> RResult<(), ()>,
152}
153
154impl DebugDisplayObject {
155 pub fn new<T>(value: T) -> DebugDisplayObject
157 where
158 T: Display + Debug + 'static,
159 {
160 DebugDisplayObject {
161 this: unsafe {
162 RBox::new(value).transmute_element::<ErasedObject>()
164 },
165 display: display_impl::<T>,
166 debug: debug_impl::<T>,
167 }
168 }
169
170 pub fn no_output() -> DebugDisplayObject {
172 Self::new(NoFmt)
173 }
174}
175
176impl Display for DebugDisplayObject {
177 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178 unsafe { adapt_std_fmt::<ErasedObject>(self.this.as_rref(), self.display, f) }
179 }
180}
181
182impl Debug for DebugDisplayObject {
183 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184 unsafe { adapt_std_fmt::<ErasedObject>(self.this.as_rref(), self.debug, f) }
185 }
186}
187
188struct NoFmt;
189
190impl Display for NoFmt {
191 fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
192 Ok(())
193 }
194}
195
196impl Debug for NoFmt {
197 fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
198 Ok(())
199 }
200}
201
202