1#![allow(non_snake_case)]
2
3use std::{
4 fmt,
5 io::{self, BufRead, Read, Write as IoWrite},
6 mem, ptr,
7};
8
9use super::*;
10
11use crate::{
12 marker_type::ErasedObject,
13 pointer_trait::{GetPointerKind, PK_MutReference, PK_Reference, PK_SmartPointer},
14 sabi_types::{RMut, RRef},
15 std_types::{RIoError, RSeekFrom},
16};
17
18use core_extensions::utils::transmute_ignore_size;
19
20pub(crate) unsafe fn adapt_std_fmt<T>(
21 value: RRef<'_, T>,
22 function: unsafe extern "C" fn(RRef<'_, T>, FormattingMode, &mut RString) -> RResult<(), ()>,
23 formatter: &mut fmt::Formatter<'_>,
24) -> fmt::Result {
25 let mut buf = RString::new();
26 let mode = if formatter.alternate() {
27 FormattingMode::Alternate
28 } else {
29 FormattingMode::Default_
30 };
31
32 unsafe { function(value, mode, &mut buf) }
33 .into_rust()
34 .map_err(|_| fmt::Error)?;
35
36 fmt::Display::fmt(&*buf, formatter)
37}
38
39pub(crate) unsafe extern "C" fn drop_pointer_impl<OrigP, ErasedPtr>(this: RMut<'_, ErasedPtr>) {
40 extern_fn_panic_handling! {no_early_return; unsafe {
41 let this = this.transmute_into_mut::<OrigP>();
42 ptr::drop_in_place(this);
43 }}
44}
45
46pub(crate) unsafe extern "C" fn clone_pointer_impl<OrigP, ErasedPtr>(
47 this: RRef<'_, ErasedPtr>,
48) -> ErasedPtr
49where
50 OrigP: Clone,
51{
52 extern_fn_panic_handling! {no_early_return;
53 let this = unsafe { this.transmute_into_ref::<OrigP>() };
54 let clone = this.clone();
55 unsafe { transmute_ignore_size(clone) }
56 }
57}
58
59pub trait DefaultImpl<PtrKind> {
68 fn default_impl() -> Self;
69}
70
71impl<This> DefaultImpl<PK_SmartPointer> for This
72where
73 Self: Default,
74{
75 fn default_impl() -> Self {
76 Default::default()
77 }
78}
79
80impl<This> DefaultImpl<PK_Reference> for This {
81 fn default_impl() -> Self {
82 unreachable!("This should not be called in DynTrait::default")
83 }
84}
85
86impl<This> DefaultImpl<PK_MutReference> for This {
87 fn default_impl() -> Self {
88 unreachable!("This should not be called in DynTrait::default")
89 }
90}
91
92pub(crate) unsafe extern "C" fn default_pointer_impl<OrigP, ErasedPtr>() -> ErasedPtr
93where
94 OrigP: GetPointerKind,
95 OrigP: DefaultImpl<<OrigP as GetPointerKind>::Kind>,
96{
97 extern_fn_panic_handling! {no_early_return; unsafe {
98 transmute_ignore_size( OrigP::default_impl() )
99 }}
100}
101
102pub(crate) unsafe extern "C" fn display_impl<T>(
105 this: RRef<'_, ErasedObject>,
106 mode: FormattingMode,
107 buf: &mut RString,
108) -> RResult<(), ()>
109where
110 T: Display,
111{
112 extern_fn_panic_handling! {no_early_return;
113 use std::fmt::Write;
114 let this = unsafe { this.transmute_into_ref::<T>() };
115
116 let res = match mode {
117 FormattingMode::Default_ => write!(buf, "{}", this),
118 FormattingMode::Alternate => write!(buf, "{:#}", this),
119 };
120 match res {
121 Ok(_) => ROk(()),
122 Err(_) => RErr(()),
123 }
124 }
125}
126
127pub(crate) unsafe extern "C" fn debug_impl<T>(
128 this: RRef<'_, ErasedObject>,
129 mode: FormattingMode,
130 buf: &mut RString,
131) -> RResult<(), ()>
132where
133 T: Debug,
134{
135 extern_fn_panic_handling! {no_early_return;
136 use std::fmt::Write;
137
138 let this = unsafe { this.transmute_into_ref::<T>() };
139
140 let res = match mode {
141 FormattingMode::Default_ => write!(buf, "{:?}", this),
142 FormattingMode::Alternate => write!(buf, "{:#?}", this),
143 };
144 match res {
145 Ok(_) => ROk(()),
146 Err(_) => RErr(()),
147 }
148 }
149}
150
151pub(crate) unsafe extern "C" fn serialize_impl<'s, T, I>(
152 this: RRef<'s, ErasedObject>,
153) -> RResult<<I as SerializeProxyType<'s>>::Proxy, RBoxError>
154where
155 T: for<'borr> SerializeType<'borr, Interface = I>,
156 I: for<'borr> SerializeProxyType<'borr>,
157{
158 extern_fn_panic_handling! {no_early_return; unsafe {
159 let ret: RResult<<I as SerializeProxyType<'_>>::Proxy, RBoxError> =
160 this
161 .transmute_into_ref::<T>()
162 .serialize_impl()
163 .into_c();
164
165 core_extensions::utils::transmute_ignore_size(ret)
166 }}
167}
168
169pub(crate) unsafe extern "C" fn partial_eq_impl<T>(
170 this: RRef<'_, ErasedObject>,
171 other: RRef<'_, ErasedObject>,
172) -> bool
173where
174 T: PartialEq,
175{
176 extern_fn_panic_handling! {no_early_return;
177 let this = unsafe { this.transmute_into_ref::<T>() };
178 let other = unsafe { other.transmute_into_ref::<T>() };
179 this == other
180 }
181}
182
183pub(crate) unsafe extern "C" fn cmp_ord<T>(
184 this: RRef<'_, ErasedObject>,
185 other: RRef<'_, ErasedObject>,
186) -> RCmpOrdering
187where
188 T: Ord,
189{
190 extern_fn_panic_handling! {no_early_return;
191 let this = unsafe { this.transmute_into_ref::<T>() };
192 let other = unsafe { other.transmute_into_ref::<T>() };
193 this.cmp(other).into_c()
194 }
195}
196
197pub(crate) unsafe extern "C" fn partial_cmp_ord<T>(
198 this: RRef<'_, ErasedObject>,
199 other: RRef<'_, ErasedObject>,
200) -> ROption<RCmpOrdering>
201where
202 T: PartialOrd,
203{
204 extern_fn_panic_handling! {no_early_return;
205 let this = unsafe { this.transmute_into_ref::<T>() };
206 let other = unsafe { other.transmute_into_ref::<T>() };
207
208 this.partial_cmp(other).map(IntoReprC::into_c).into_c()
209 }
210}
211
212pub(crate) unsafe extern "C" fn hash_Hash<T>(
216 this: RRef<'_, ErasedObject>,
217 mut state: trait_objects::HasherObject<'_>,
218) where
219 T: Hash,
220{
221 extern_fn_panic_handling! {no_early_return;
222 let this = unsafe { this.transmute_into_ref::<T>() };
223
224 this.hash(&mut state);
225 }
226}
227
228pub(crate) unsafe extern "C" fn write_Hasher<T>(this: RMut<'_, ErasedObject>, slic_: RSlice<'_, u8>)
232where
233 T: Hasher,
234{
235 extern_fn_panic_handling! {
236 let this = unsafe { this.transmute_into_mut::<T>() };
237 this.write(slic_.into());
238 }
239}
240
241macro_rules! fn_write {
242 ( $(($ty:ty, $delegated_fn:ident, $new_fn:ident)),* ) => {
243 $(
244 pub(crate) unsafe extern "C" fn $new_fn<T>(
245 this: RMut<'_, ErasedObject>,
246 val: $ty,
247 ) where
248 T: Hasher,
249 {
250 extern_fn_panic_handling! {
251 let this = unsafe { this.transmute_into_mut::<T>() };
252 this.$delegated_fn(val);
253 }
254 }
255 )*
256 }
257}
258
259fn_write!(
260 (i16, write_i16, write_i16_Hasher),
263 (i32, write_i32, write_i32_Hasher),
264 (i64, write_i64, write_i64_Hasher),
265 (i8, write_i8, write_i8_Hasher),
266 (isize, write_isize, write_isize_Hasher),
267 (u16, write_u16, write_u16_Hasher),
270 (u32, write_u32, write_u32_Hasher),
271 (u64, write_u64, write_u64_Hasher),
272 (u8, write_u8, write_u8_Hasher),
273 (usize, write_usize, write_usize_Hasher)
274);
275
276pub(crate) unsafe extern "C" fn finish_Hasher<T>(this: RRef<'_, ErasedObject>) -> u64
277where
278 T: Hasher,
279{
280 extern_fn_panic_handling! {
281 let this = unsafe { this.transmute_into_ref::<T>() };
282
283 this.finish()
284 }
285}
286
287pub(super) unsafe extern "C" fn write_str_fmt_write<T>(
292 this: RMut<'_, ErasedObject>,
293 data: RStr<'_>,
294) -> RResult<(), ()>
295where
296 T: fmt::Write,
297{
298 extern_fn_panic_handling! {
299 let this = unsafe { this.transmute_into_mut::<T>() };
300 match fmt::Write::write_str(this,data.as_str()) {
301 Ok(())=>ROk(()),
302 Err(_)=>RErr(()),
303 }
304 }
305}
306
307#[inline]
312fn convert_io_result<T, U>(res: io::Result<T>) -> RResult<U, RIoError>
313where
314 T: Into<U>,
315{
316 match res {
317 Ok(v) => ROk(v.into()),
318 Err(e) => RErr(RIoError::from(e)),
319 }
320}
321
322#[repr(C)]
325#[derive(StableAbi, Copy, Clone)]
326pub struct IoWriteFns {
327 pub(super) write: unsafe extern "C" fn(
328 RMut<'_, ErasedObject>,
329 buf: RSlice<'_, u8>,
330 ) -> RResult<usize, RIoError>,
331
332 pub(super) write_all:
333 unsafe extern "C" fn(RMut<'_, ErasedObject>, buf: RSlice<'_, u8>) -> RResult<(), RIoError>,
334
335 pub(super) flush: unsafe extern "C" fn(RMut<'_, ErasedObject>) -> RResult<(), RIoError>,
336}
337
338pub(super) struct MakeIoWriteFns<W>(W);
339
340impl<W> MakeIoWriteFns<W>
341where
342 W: IoWrite,
343{
344 pub(super) const NEW: IoWriteFns = IoWriteFns {
345 write: io_Write_write::<W>,
346 write_all: io_Write_write_all::<W>,
347 flush: io_Write_flush::<W>,
348 };
349}
350
351pub(super) unsafe extern "C" fn io_Write_write<W>(
352 this: RMut<'_, ErasedObject>,
353 buf: RSlice<'_, u8>,
354) -> RResult<usize, RIoError>
355where
356 W: IoWrite,
357{
358 extern_fn_panic_handling! {no_early_return;
359 let this = unsafe { this.transmute_into_mut::<W>() };
360
361 convert_io_result(this.write(buf.into()))
362 }
363}
364
365pub(super) unsafe extern "C" fn io_Write_write_all<W>(
366 this: RMut<'_, ErasedObject>,
367 buf: RSlice<'_, u8>,
368) -> RResult<(), RIoError>
369where
370 W: IoWrite,
371{
372 extern_fn_panic_handling! {no_early_return;
373 let this = unsafe { this.transmute_into_mut::<W>() };
374
375 convert_io_result(this.write_all(buf.into()))
376 }
377}
378
379pub(super) unsafe extern "C" fn io_Write_flush<W>(
380 this: RMut<'_, ErasedObject>,
381) -> RResult<(), RIoError>
382where
383 W: IoWrite,
384{
385 extern_fn_panic_handling! {no_early_return;
386 let this = unsafe { this.transmute_into_mut::<W>() };
387
388 convert_io_result(this.flush())
389 }
390}
391
392#[repr(C)]
395#[derive(StableAbi, Copy, Clone)]
396pub struct IoReadFns {
397 pub(super) read:
398 unsafe extern "C" fn(RMut<'_, ErasedObject>, RSliceMut<'_, u8>) -> RResult<usize, RIoError>,
399
400 pub(super) read_exact:
401 unsafe extern "C" fn(RMut<'_, ErasedObject>, RSliceMut<'_, u8>) -> RResult<(), RIoError>,
402}
403
404pub(super) struct MakeIoReadFns<W>(W);
405
406impl<W> MakeIoReadFns<W>
407where
408 W: io::Read,
409{
410 pub(super) const NEW: IoReadFns = IoReadFns {
411 read: io_Read_read::<W>,
412 read_exact: io_Read_read_exact::<W>,
413 };
414}
415
416pub(super) unsafe extern "C" fn io_Read_read<R>(
417 this: RMut<'_, ErasedObject>,
418 buf: RSliceMut<'_, u8>,
419) -> RResult<usize, RIoError>
420where
421 R: Read,
422{
423 extern_fn_panic_handling! {no_early_return;
424 let this = unsafe { this.transmute_into_mut::<R>() };
425
426 convert_io_result(this.read(buf.into()))
427 }
428}
429
430pub(super) unsafe extern "C" fn io_Read_read_exact<R>(
431 this: RMut<'_, ErasedObject>,
432 buf: RSliceMut<'_, u8>,
433) -> RResult<(), RIoError>
434where
435 R: Read,
436{
437 extern_fn_panic_handling! {no_early_return;
438 let this = unsafe { this.transmute_into_mut::<R>() };
439
440 convert_io_result(this.read_exact(buf.into()))
441 }
442}
443
444#[repr(C)]
447#[derive(StableAbi, Copy, Clone)]
448pub struct IoBufReadFns {
449 pub(super) fill_buf:
450 unsafe extern "C" fn(RMut<'_, ErasedObject>) -> RResult<RSlice<'_, u8>, RIoError>,
451
452 pub(super) consume: unsafe extern "C" fn(RMut<'_, ErasedObject>, usize),
453}
454
455pub(super) struct MakeIoBufReadFns<W>(W);
456
457impl<W> MakeIoBufReadFns<W>
458where
459 W: io::BufRead,
460{
461 pub(super) const NEW: IoBufReadFns = IoBufReadFns {
462 fill_buf: io_BufRead_fill_buf::<W>,
463 consume: io_BufRead_consume::<W>,
464 };
465}
466
467pub(super) unsafe extern "C" fn io_BufRead_fill_buf<R>(
468 this: RMut<'_, ErasedObject>,
469) -> RResult<RSlice<'_, u8>, RIoError>
470where
471 R: BufRead,
472{
473 extern_fn_panic_handling! {no_early_return; unsafe {
474 let this = this.transmute_into_mut::<R>();
475
476 mem::transmute::<
481 RResult<RSlice<'_,u8>,RIoError>,
482 RResult<RSlice<'_,u8>,RIoError>
483 >(convert_io_result(this.fill_buf()))
484 }}
485}
486
487pub(super) unsafe extern "C" fn io_BufRead_consume<R>(this: RMut<'_, ErasedObject>, amount: usize)
488where
489 R: BufRead,
490{
491 extern_fn_panic_handling! {no_early_return;
492 let this = unsafe { this.transmute_into_mut::<R>() };
493
494 this.consume(amount)
495 }
496}
497
498pub(super) unsafe extern "C" fn io_Seek_seek<S>(
501 this: RMut<'_, ErasedObject>,
502 seek_from: RSeekFrom,
503) -> RResult<u64, RIoError>
504where
505 S: io::Seek,
506{
507 extern_fn_panic_handling! {no_early_return;
508 let this = unsafe { this.transmute_into_mut::<S>() };
509
510 convert_io_result(this.seek(seek_from.into()))
511 }
512}