1use std::any::Any;
19
20pub trait ForyObject: Any {
25 fn as_any(&self) -> &dyn Any;
26}
27
28impl<T: Any> ForyObject for T {
29 #[inline(always)]
30 fn as_any(&self) -> &dyn Any {
31 self
32 }
33}
34
35#[macro_export]
64macro_rules! register_trait_type {
65 ($vis:vis sync $trait_name:ident, $($target:ty),+ $(,)?) => {
66 $crate::register_trait_type!(@dispatch $trait_name, $($target),+);
67 $crate::register_trait_type!(@box [$vis] $trait_name, $($target),+);
68 $crate::register_trait_type!(@rc [$vis] $trait_name, $($target),+);
69 $crate::register_trait_type!(@arc [$vis] $trait_name, $($target),+);
70 };
71
72 ($vis:vis $trait_name:ident, $($target:ty),+ $(,)?) => {
73 $crate::register_trait_type!(@dispatch $trait_name, $($target),+);
74 $crate::register_trait_type!(@box [$vis] $trait_name, $($target),+);
75 $crate::register_trait_type!(@rc [$vis] $trait_name, $($target),+);
76 };
77
78 (@dispatch $trait_name:ident, $($target:ty),+) => {
79 $crate::paste::paste! {
80 #[allow(dead_code)]
81 struct [<$trait_name ForyDispatch>];
82
83 #[allow(dead_code)]
84 impl [<$trait_name ForyDispatch>] {
85 #[inline(always)]
86 fn any_ref(value: &dyn $trait_name) -> &dyn std::any::Any {
87 <dyn $trait_name as $crate::ForyObject>::as_any(value)
88 }
89
90 #[inline(always)]
91 fn ensure_member(
92 target_type_id: std::any::TypeId,
93 ) -> Result<(), $crate::Error> {
94 if !($(target_type_id == std::any::TypeId::of::<$target>())||+) {
95 return Err(Self::unlisted(target_type_id));
96 }
97 Ok(())
98 }
99
100 #[inline(always)]
101 fn checked_any(
102 value: &dyn $trait_name,
103 ) -> Result<&dyn std::any::Any, $crate::Error> {
104 let any = Self::any_ref(value);
105 Self::ensure_member(any.type_id())?;
106 Ok(any)
107 }
108
109 #[inline(always)]
110 fn target_id(
111 type_info: &$crate::TypeInfo,
112 ) -> Result<std::any::TypeId, $crate::Error> {
113 type_info
114 .get_harness()
115 .target_type_id()
116 .ok_or_else(Self::missing)
117 }
118
119 #[inline(always)]
120 fn check_type_info(
121 target_type_id: std::any::TypeId,
122 type_info: &$crate::TypeInfo,
123 ) -> Result<(), $crate::Error> {
124 $crate::serializer::any::check_erased_target_type(type_info)?;
125 let resolved_target_type_id = Self::target_id(type_info)?;
126 if resolved_target_type_id != target_type_id {
127 return Err(Self::downcast(
128 resolved_target_type_id,
129 target_type_id,
130 ));
131 }
132 Ok(())
133 }
134
135 #[inline(always)]
136 fn resolve_type_info(
137 context: &mut $crate::WriteContext,
138 target_type_id: std::any::TypeId,
139 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
140 let type_info = context.get_target_type_info(&target_type_id)?;
141 Self::check_type_info(target_type_id, &type_info)?;
142 Ok(type_info)
143 }
144
145 #[inline(always)]
146 fn write_type_info_value(
147 context: &mut $crate::WriteContext,
148 target_type_id: std::any::TypeId,
149 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
150 Self::ensure_member(target_type_id)?;
151 let type_info = Self::resolve_type_info(context, target_type_id)?;
152 context.write_resolved_type_info(
153 $crate::TypeId::UNKNOWN as u32,
154 type_info,
155 )
156 }
157
158 #[inline(always)]
159 fn write_harness(
160 any: &dyn std::any::Any,
161 context: &mut $crate::WriteContext,
162 type_info: &std::rc::Rc<$crate::TypeInfo>,
163 ) -> Result<(), $crate::Error> {
164 type_info.get_harness().write_data(any, context)
165 }
166
167 #[inline(always)]
168 fn write_checked(
169 any: &dyn std::any::Any,
170 context: &mut $crate::WriteContext,
171 write_type_info: bool,
172 ) -> Result<(), $crate::Error> {
173 let type_info = Self::resolve_type_info(context, any.type_id())?;
174 let type_info = if write_type_info {
175 context.write_resolved_type_info(
176 $crate::TypeId::UNKNOWN as u32,
177 type_info,
178 )?
179 } else {
180 type_info
181 };
182 Self::write_harness(any, context, &type_info)
183 }
184
185 #[inline(always)]
186 fn write_data(
187 value: &dyn $trait_name,
188 context: &mut $crate::WriteContext,
189 write_type_info: bool,
190 ) -> Result<(), $crate::Error> {
191 let any = Self::checked_any(value)?;
192 Self::write_checked(any, context, write_type_info)
193 }
194
195 #[inline(always)]
196 fn read_box(
197 context: &mut $crate::ReadContext,
198 type_info: &std::rc::Rc<$crate::TypeInfo>,
199 ) -> Result<Box<dyn $trait_name>, $crate::Error> {
200 let target_type_id = Self::target_id(type_info)?;
201 $crate::serializer::any::check_erased_target_type(type_info)?;
202 $(
203 if target_type_id == std::any::TypeId::of::<$target>() {
204 let erased = type_info
205 .get_harness()
206 .read_box_any(context, type_info)?;
207 let concrete = erased.downcast::<$target>().map_err(|value| {
208 Self::downcast(target_type_id, value.as_ref().type_id())
209 })?;
210 let value: Box<dyn $trait_name> = concrete;
211 return Ok(value);
212 }
213 )+
214 Err(Self::unlisted(target_type_id))
215 }
216
217 #[inline(always)]
218 fn read_rc(
219 context: &mut $crate::ReadContext,
220 type_info: &std::rc::Rc<$crate::TypeInfo>,
221 ) -> Result<std::rc::Rc<dyn $trait_name>, $crate::Error> {
222 let target_type_id = Self::target_id(type_info)?;
223 $crate::serializer::any::check_erased_target_type(type_info)?;
224 $(
225 if target_type_id == std::any::TypeId::of::<$target>() {
226 let erased = type_info
227 .get_harness()
228 .read_rc_any(context, type_info)?;
229 let concrete = erased.downcast::<$target>().map_err(|value| {
230 Self::downcast(target_type_id, value.as_ref().type_id())
231 })?;
232 let value: std::rc::Rc<dyn $trait_name> = concrete;
233 return Ok(value);
234 }
235 )+
236 Err(Self::unlisted(target_type_id))
237 }
238
239 #[cold]
240 #[inline(never)]
241 fn unlisted(target_type_id: std::any::TypeId) -> $crate::Error {
242 $crate::Error::type_error(format!(
243 "target TypeId {:?} is not listed for application trait {}",
244 target_type_id,
245 stringify!($trait_name),
246 ))
247 }
248
249 #[cold]
250 #[inline(never)]
251 fn missing() -> $crate::Error {
252 $crate::Error::type_error(format!(
253 "application trait {} metadata has no checked local target registration",
254 stringify!($trait_name),
255 ))
256 }
257
258 #[cold]
259 #[inline(never)]
260 fn downcast(
261 expected: std::any::TypeId,
262 actual: std::any::TypeId,
263 ) -> $crate::Error {
264 $crate::Error::type_error(format!(
265 "application trait {} expected target TypeId {:?}, got {:?}",
266 stringify!($trait_name),
267 expected,
268 actual,
269 ))
270 }
271
272 #[cold]
273 #[inline(never)]
274 fn missing_ref(ref_id: u32) -> $crate::Error {
275 $crate::Error::invalid_data(format!(
276 "dyn {} reference {} not found",
277 stringify!($trait_name),
278 ref_id,
279 ))
280 }
281 }
282 }
283 };
284
285 (@box [$vis:vis] $trait_name:ident, $($target:ty),+) => {
286 $crate::paste::paste! {
287 #[allow(dead_code)]
288 impl [<$trait_name ForyDispatch>] {
289 #[cold]
290 #[inline(never)]
291 fn null_box_value() -> $crate::Error {
292 $crate::Error::invalid_ref(concat!(
293 "Box<dyn ",
294 stringify!($trait_name),
295 "> cannot be null",
296 ))
297 }
298
299 #[cold]
300 #[inline(never)]
301 fn missing_box_metadata() -> $crate::Error {
302 $crate::Error::invalid_data(concat!(
303 "Box<dyn ",
304 stringify!($trait_name),
305 "> requires concrete type metadata",
306 ))
307 }
308 }
309
310 impl $crate::Serializer for Box<dyn $trait_name> {
311 type Target = Self;
312 #[inline(always)]
313 fn write_data(
314 value: &Self,
315 context: &mut $crate::WriteContext,
316 ) -> Result<(), $crate::Error> {
317 [<$trait_name ForyDispatch>]::write_data(
318 value.as_ref(),
319 context,
320 false,
321 )
322 }
323
324 #[cold]
325 #[inline(never)]
326 fn read_data(
327 _context: &mut $crate::ReadContext,
328 ) -> Result<Self, $crate::Error> {
329 Err($crate::Error::not_allowed(concat!(
330 "Box<dyn ",
331 stringify!($trait_name),
332 "> requires concrete type metadata",
333 )))
334 }
335
336 #[inline(always)]
337 fn write_type_info_value(
338 context: &mut $crate::WriteContext,
339 target_type_id: std::any::TypeId,
340 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
341 [<$trait_name ForyDispatch>]::write_type_info_value(
342 context,
343 target_type_id,
344 )
345 }
346
347 #[inline(always)]
348 fn write_with_type_info(
349 value: &Self,
350 context: &mut $crate::WriteContext,
351 ref_mode: $crate::RefMode,
352 type_info: &std::rc::Rc<$crate::TypeInfo>,
353 ) -> Result<(), $crate::Error> {
354 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
355 [<$trait_name ForyDispatch>]::check_type_info(any.type_id(), type_info)?;
356 if ref_mode != $crate::RefMode::None {
357 context.writer.write_i8($crate::RefFlag::NotNullValue as i8);
358 }
359 [<$trait_name ForyDispatch>]::write_harness(
360 any,
361 context,
362 type_info,
363 )
364 }
365
366 #[inline(always)]
367 fn write(
368 value: &Self,
369 context: &mut $crate::WriteContext,
370 ref_mode: $crate::RefMode,
371 write_type_info: bool,
372 ) -> Result<(), $crate::Error> {
373 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
374 if ref_mode != $crate::RefMode::None {
375 context.writer.write_i8($crate::RefFlag::NotNullValue as i8);
376 }
377 [<$trait_name ForyDispatch>]::write_checked(
378 any,
379 context,
380 write_type_info,
381 )
382 }
383
384 #[inline(always)]
385 fn read(
386 context: &mut $crate::ReadContext,
387 ref_mode: $crate::RefMode,
388 read_type_info: bool,
389 ) -> Result<Self, $crate::Error> {
390 context.inc_depth()?;
391 let value = (|| {
392 if ref_mode != $crate::RefMode::None
393 && context.reader.read_i8()?
394 != $crate::RefFlag::NotNullValue as i8
395 {
396 return Err([<$trait_name ForyDispatch>]::null_box_value());
397 }
398 if !read_type_info {
399 return Err([<$trait_name ForyDispatch>]::missing_box_metadata());
400 }
401 let type_info = context.read_any_type_info()?;
402 [<$trait_name ForyDispatch>]::read_box(context, &type_info)
403 })()?;
404 context.dec_depth();
405 Ok(value)
406 }
407
408 #[inline(always)]
409 fn read_with_type_info(
410 context: &mut $crate::ReadContext,
411 ref_mode: $crate::RefMode,
412 type_info: &std::rc::Rc<$crate::TypeInfo>,
413 ) -> Result<Self, $crate::Error> {
414 context.inc_depth()?;
415 let value = (|| {
416 if ref_mode != $crate::RefMode::None
417 && context.reader.read_i8()?
418 != $crate::RefFlag::NotNullValue as i8
419 {
420 return Err([<$trait_name ForyDispatch>]::null_box_value());
421 }
422 [<$trait_name ForyDispatch>]::read_box(context, type_info)
423 })()?;
424 context.dec_depth();
425 Ok(value)
426 }
427
428 #[inline(always)]
429 fn write_type_info(
430 _context: &mut $crate::WriteContext,
431 ) -> Result<(), $crate::Error> {
432 Ok(())
433 }
434
435 #[inline(always)]
436 fn read_type_info(
437 _context: &mut $crate::ReadContext,
438 ) -> Result<(), $crate::Error> {
439 Ok(())
440 }
441
442 #[inline(always)]
443 fn static_type_id() -> $crate::TypeId {
444 $crate::TypeId::UNKNOWN
445 }
446
447 #[inline(always)]
448 fn reserved_space() -> usize {
449 $crate::type_id::SIZE_OF_REF_AND_TYPE
450 }
451
452 const IS_POLYMORPHIC: bool = true;
453
454 const IS_WRAPPER: bool = true;
455
456 #[inline(always)]
457 fn dynamic_type_id(
458 value: &Self,
459 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
460 Ok(Some(
461 [<$trait_name ForyDispatch>]::any_ref(value.as_ref()).type_id(),
462 ))
463 }
464 }
465
466 $crate::register_trait_type!(
467 @codec
468 [$vis]
469 [<$trait_name BoxCodec>],
470 Box<dyn $trait_name>,
471 Box<dyn $trait_name>
472 );
473 }
474 };
475
476 (@rc [$vis:vis] $trait_name:ident, $($target:ty),+) => {
477 $crate::paste::paste! {
478 #[allow(dead_code)]
479 impl [<$trait_name ForyDispatch>] {
480 #[cold]
481 #[inline(never)]
482 fn null_rc_value() -> $crate::Error {
483 $crate::Error::invalid_ref(concat!(
484 "Rc<dyn ",
485 stringify!($trait_name),
486 "> cannot be null",
487 ))
488 }
489
490 #[cold]
491 #[inline(never)]
492 fn missing_rc_metadata() -> $crate::Error {
493 $crate::Error::invalid_data(concat!(
494 "Rc<dyn ",
495 stringify!($trait_name),
496 "> requires concrete type metadata",
497 ))
498 }
499 }
500
501 #[allow(dead_code)]
502 #[doc = concat!("Serializer for `Rc<dyn ", stringify!($trait_name), ">`.")]
503 $vis struct [<$trait_name RcSerializer>](std::marker::PhantomData<()>);
504
505 impl $crate::Serializer for [<$trait_name RcSerializer>] {
506 type Target = std::rc::Rc<dyn $trait_name>;
507 #[inline(always)]
508 fn write_data(
509 value: &Self::Target,
510 context: &mut $crate::WriteContext,
511 ) -> Result<(), $crate::Error> {
512 [<$trait_name ForyDispatch>]::write_data(
513 value.as_ref(),
514 context,
515 false,
516 )
517 }
518
519 #[cold]
520 #[inline(never)]
521 fn read_data(
522 _context: &mut $crate::ReadContext,
523 ) -> Result<Self::Target, $crate::Error> {
524 Err($crate::Error::not_allowed(concat!(
525 "Rc<dyn ",
526 stringify!($trait_name),
527 "> requires concrete type metadata",
528 )))
529 }
530
531 #[inline(always)]
532 fn write_type_info_value(
533 context: &mut $crate::WriteContext,
534 target_type_id: std::any::TypeId,
535 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
536 [<$trait_name ForyDispatch>]::write_type_info_value(
537 context,
538 target_type_id,
539 )
540 }
541
542 #[inline(always)]
543 fn write_with_type_info(
544 value: &Self::Target,
545 context: &mut $crate::WriteContext,
546 ref_mode: $crate::RefMode,
547 type_info: &std::rc::Rc<$crate::TypeInfo>,
548 ) -> Result<(), $crate::Error> {
549 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
550 [<$trait_name ForyDispatch>]::check_type_info(any.type_id(), type_info)?;
551 if ref_mode != $crate::RefMode::None
552 && context
553 .ref_writer
554 .try_write_rc_ref(&mut context.writer, value)
555 {
556 return Ok(());
557 }
558 [<$trait_name ForyDispatch>]::write_harness(
559 any,
560 context,
561 type_info,
562 )
563 }
564
565 #[inline(always)]
566 fn write(
567 value: &Self::Target,
568 context: &mut $crate::WriteContext,
569 ref_mode: $crate::RefMode,
570 write_type_info: bool,
571 ) -> Result<(), $crate::Error> {
572 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
573 if ref_mode != $crate::RefMode::None
574 && context
575 .ref_writer
576 .try_write_rc_ref(&mut context.writer, value)
577 {
578 return Ok(());
579 }
580 [<$trait_name ForyDispatch>]::write_checked(
581 any,
582 context,
583 write_type_info,
584 )
585 }
586
587 #[inline(always)]
588 fn read(
589 context: &mut $crate::ReadContext,
590 ref_mode: $crate::RefMode,
591 read_type_info: bool,
592 ) -> Result<Self::Target, $crate::Error> {
593 let ref_flag = if ref_mode != $crate::RefMode::None {
594 context.ref_reader.read_ref_flag(&mut context.reader)?
595 } else {
596 $crate::RefFlag::NotNullValue
597 };
598 match ref_flag {
599 $crate::RefFlag::Null => {
600 Err([<$trait_name ForyDispatch>]::null_rc_value())
601 }
602 $crate::RefFlag::Ref => {
603 let ref_id =
604 context.ref_reader.read_ref_id(&mut context.reader)?;
605 context
606 .ref_reader
607 .get_rc_ref::<dyn $trait_name>(ref_id)
608 .ok_or_else(|| {
609 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
610 })
611 }
612 $crate::RefFlag::NotNullValue => {
613 context.inc_depth()?;
614 let value = (|| {
615 if !read_type_info {
616 return Err(
617 [<$trait_name ForyDispatch>]::missing_rc_metadata()
618 );
619 }
620 let type_info = context.read_any_type_info()?;
621 [<$trait_name ForyDispatch>]::read_rc(context, &type_info)
622 })()?;
623 context.dec_depth();
624 Ok(value)
625 }
626 $crate::RefFlag::RefValue => {
627 let ref_id = context.ref_reader.reserve_ref_id();
628 context.inc_depth()?;
629 let value = (|| {
630 if !read_type_info {
631 return Err(
632 [<$trait_name ForyDispatch>]::missing_rc_metadata()
633 );
634 }
635 let type_info = context.read_any_type_info()?;
636 [<$trait_name ForyDispatch>]::read_rc(context, &type_info)
637 })()?;
638 context.dec_depth();
639 context.ref_reader.store_rc_ref_at(ref_id, value.clone());
640 Ok(value)
641 }
642 }
643 }
644
645 #[inline(always)]
646 fn read_with_type_info(
647 context: &mut $crate::ReadContext,
648 ref_mode: $crate::RefMode,
649 type_info: &std::rc::Rc<$crate::TypeInfo>,
650 ) -> Result<Self::Target, $crate::Error> {
651 let ref_flag = if ref_mode != $crate::RefMode::None {
652 context.ref_reader.read_ref_flag(&mut context.reader)?
653 } else {
654 $crate::RefFlag::NotNullValue
655 };
656 match ref_flag {
657 $crate::RefFlag::Null => {
658 Err([<$trait_name ForyDispatch>]::null_rc_value())
659 }
660 $crate::RefFlag::Ref => {
661 let ref_id =
662 context.ref_reader.read_ref_id(&mut context.reader)?;
663 context
664 .ref_reader
665 .get_rc_ref::<dyn $trait_name>(ref_id)
666 .ok_or_else(|| {
667 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
668 })
669 }
670 $crate::RefFlag::NotNullValue => {
671 context.inc_depth()?;
672 let value =
673 [<$trait_name ForyDispatch>]::read_rc(context, type_info)?;
674 context.dec_depth();
675 Ok(value)
676 }
677 $crate::RefFlag::RefValue => {
678 let ref_id = context.ref_reader.reserve_ref_id();
679 context.inc_depth()?;
680 let value =
681 [<$trait_name ForyDispatch>]::read_rc(context, type_info)?;
682 context.dec_depth();
683 context.ref_reader.store_rc_ref_at(ref_id, value.clone());
684 Ok(value)
685 }
686 }
687 }
688
689 #[inline(always)]
690 fn write_type_info(
691 _context: &mut $crate::WriteContext,
692 ) -> Result<(), $crate::Error> {
693 Ok(())
694 }
695
696 #[inline(always)]
697 fn read_type_info(
698 _context: &mut $crate::ReadContext,
699 ) -> Result<(), $crate::Error> {
700 Ok(())
701 }
702
703 #[inline(always)]
704 fn static_type_id() -> $crate::TypeId {
705 $crate::TypeId::UNKNOWN
706 }
707
708 #[inline(always)]
709 fn reserved_space() -> usize {
710 $crate::type_id::SIZE_OF_REF_AND_TYPE
711 }
712
713 const IS_POLYMORPHIC: bool = true;
714
715 const IS_SHARED_REF: bool = true;
716
717 const IS_WRAPPER: bool = true;
718
719 #[inline(always)]
720 fn dynamic_type_id(
721 value: &Self::Target,
722 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
723 Ok(Some(
724 [<$trait_name ForyDispatch>]::any_ref(value.as_ref()).type_id(),
725 ))
726 }
727 }
728
729 $crate::register_trait_type!(
730 @codec
731 [$vis]
732 [<$trait_name RcCodec>],
733 [<$trait_name RcSerializer>],
734 std::rc::Rc<dyn $trait_name>
735 );
736 }
737 };
738
739 (@arc [$vis:vis] $trait_name:ident, $($target:ty),+) => {
740 $crate::paste::paste! {
741 const _: () = {
742 fn assert_sync<T: ?Sized + Send + Sync>() {}
743 let _ = assert_sync::<dyn $trait_name>;
744 $(let _ = assert_sync::<$target>;)+
745 };
746
747 #[allow(dead_code)]
748 impl [<$trait_name ForyDispatch>] {
749 #[cold]
750 #[inline(never)]
751 fn null_arc_value() -> $crate::Error {
752 $crate::Error::invalid_ref(concat!(
753 "Arc<dyn ",
754 stringify!($trait_name),
755 "> cannot be null",
756 ))
757 }
758
759 #[cold]
760 #[inline(never)]
761 fn missing_arc_metadata() -> $crate::Error {
762 $crate::Error::invalid_data(concat!(
763 "Arc<dyn ",
764 stringify!($trait_name),
765 "> requires concrete type metadata",
766 ))
767 }
768
769 #[inline(always)]
770 fn read_arc(
771 context: &mut $crate::ReadContext,
772 type_info: &std::rc::Rc<$crate::TypeInfo>,
773 ) -> Result<std::sync::Arc<dyn $trait_name>, $crate::Error> {
774 let target_type_id = Self::target_id(type_info)?;
775 $crate::serializer::any::check_erased_target_type(type_info)?;
776 $(
777 if target_type_id == std::any::TypeId::of::<$target>() {
778 let erased = type_info
779 .get_harness()
780 .read_arc_any(context, type_info)?;
781 let concrete = erased.downcast::<$target>().map_err(|value| {
782 Self::downcast(target_type_id, value.as_ref().type_id())
783 })?;
784 let value: std::sync::Arc<dyn $trait_name> = concrete;
785 return Ok(value);
786 }
787 )+
788 Err(Self::unlisted(target_type_id))
789 }
790 }
791
792 #[allow(dead_code)]
793 #[doc = concat!("Serializer for `Arc<dyn ", stringify!($trait_name), ">`.")]
794 $vis struct [<$trait_name ArcSerializer>](std::marker::PhantomData<()>);
795
796 impl $crate::Serializer for [<$trait_name ArcSerializer>] {
797 type Target = std::sync::Arc<dyn $trait_name>;
798 #[inline(always)]
799 fn write_data(
800 value: &Self::Target,
801 context: &mut $crate::WriteContext,
802 ) -> Result<(), $crate::Error> {
803 [<$trait_name ForyDispatch>]::write_data(
804 value.as_ref(),
805 context,
806 false,
807 )
808 }
809
810 #[cold]
811 #[inline(never)]
812 fn read_data(
813 _context: &mut $crate::ReadContext,
814 ) -> Result<Self::Target, $crate::Error> {
815 Err($crate::Error::not_allowed(concat!(
816 "Arc<dyn ",
817 stringify!($trait_name),
818 "> requires concrete type metadata",
819 )))
820 }
821
822 #[inline(always)]
823 fn write_type_info_value(
824 context: &mut $crate::WriteContext,
825 target_type_id: std::any::TypeId,
826 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
827 [<$trait_name ForyDispatch>]::write_type_info_value(
828 context,
829 target_type_id,
830 )
831 }
832
833 #[inline(always)]
834 fn write_with_type_info(
835 value: &Self::Target,
836 context: &mut $crate::WriteContext,
837 ref_mode: $crate::RefMode,
838 type_info: &std::rc::Rc<$crate::TypeInfo>,
839 ) -> Result<(), $crate::Error> {
840 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
841 [<$trait_name ForyDispatch>]::check_type_info(any.type_id(), type_info)?;
842 if ref_mode != $crate::RefMode::None
843 && context
844 .ref_writer
845 .try_write_arc_ref(&mut context.writer, value)
846 {
847 return Ok(());
848 }
849 [<$trait_name ForyDispatch>]::write_harness(
850 any,
851 context,
852 type_info,
853 )
854 }
855
856 #[inline(always)]
857 fn write(
858 value: &Self::Target,
859 context: &mut $crate::WriteContext,
860 ref_mode: $crate::RefMode,
861 write_type_info: bool,
862 ) -> Result<(), $crate::Error> {
863 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
864 if ref_mode != $crate::RefMode::None
865 && context
866 .ref_writer
867 .try_write_arc_ref(&mut context.writer, value)
868 {
869 return Ok(());
870 }
871 [<$trait_name ForyDispatch>]::write_checked(
872 any,
873 context,
874 write_type_info,
875 )
876 }
877
878 #[inline(always)]
879 fn read(
880 context: &mut $crate::ReadContext,
881 ref_mode: $crate::RefMode,
882 read_type_info: bool,
883 ) -> Result<Self::Target, $crate::Error> {
884 let ref_flag = if ref_mode != $crate::RefMode::None {
885 context.ref_reader.read_ref_flag(&mut context.reader)?
886 } else {
887 $crate::RefFlag::NotNullValue
888 };
889 match ref_flag {
890 $crate::RefFlag::Null => {
891 Err([<$trait_name ForyDispatch>]::null_arc_value())
892 }
893 $crate::RefFlag::Ref => {
894 let ref_id =
895 context.ref_reader.read_ref_id(&mut context.reader)?;
896 context
897 .ref_reader
898 .get_arc_ref::<dyn $trait_name>(ref_id)
899 .ok_or_else(|| {
900 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
901 })
902 }
903 $crate::RefFlag::NotNullValue => {
904 context.inc_depth()?;
905 let value = (|| {
906 if !read_type_info {
907 return Err(
908 [<$trait_name ForyDispatch>]::missing_arc_metadata()
909 );
910 }
911 let type_info = context.read_any_type_info()?;
912 [<$trait_name ForyDispatch>]::read_arc(context, &type_info)
913 })()?;
914 context.dec_depth();
915 Ok(value)
916 }
917 $crate::RefFlag::RefValue => {
918 let ref_id = context.ref_reader.reserve_ref_id();
919 context.inc_depth()?;
920 let value = (|| {
921 if !read_type_info {
922 return Err(
923 [<$trait_name ForyDispatch>]::missing_arc_metadata()
924 );
925 }
926 let type_info = context.read_any_type_info()?;
927 [<$trait_name ForyDispatch>]::read_arc(context, &type_info)
928 })()?;
929 context.dec_depth();
930 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
931 Ok(value)
932 }
933 }
934 }
935
936 #[inline(always)]
937 fn read_with_type_info(
938 context: &mut $crate::ReadContext,
939 ref_mode: $crate::RefMode,
940 type_info: &std::rc::Rc<$crate::TypeInfo>,
941 ) -> Result<Self::Target, $crate::Error> {
942 let ref_flag = if ref_mode != $crate::RefMode::None {
943 context.ref_reader.read_ref_flag(&mut context.reader)?
944 } else {
945 $crate::RefFlag::NotNullValue
946 };
947 match ref_flag {
948 $crate::RefFlag::Null => {
949 Err([<$trait_name ForyDispatch>]::null_arc_value())
950 }
951 $crate::RefFlag::Ref => {
952 let ref_id =
953 context.ref_reader.read_ref_id(&mut context.reader)?;
954 context
955 .ref_reader
956 .get_arc_ref::<dyn $trait_name>(ref_id)
957 .ok_or_else(|| {
958 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
959 })
960 }
961 $crate::RefFlag::NotNullValue => {
962 context.inc_depth()?;
963 let value =
964 [<$trait_name ForyDispatch>]::read_arc(context, type_info)?;
965 context.dec_depth();
966 Ok(value)
967 }
968 $crate::RefFlag::RefValue => {
969 let ref_id = context.ref_reader.reserve_ref_id();
970 context.inc_depth()?;
971 let value =
972 [<$trait_name ForyDispatch>]::read_arc(context, type_info)?;
973 context.dec_depth();
974 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
975 Ok(value)
976 }
977 }
978 }
979
980 #[inline(always)]
981 fn write_type_info(
982 _context: &mut $crate::WriteContext,
983 ) -> Result<(), $crate::Error> {
984 Ok(())
985 }
986
987 #[inline(always)]
988 fn read_type_info(
989 _context: &mut $crate::ReadContext,
990 ) -> Result<(), $crate::Error> {
991 Ok(())
992 }
993
994 #[inline(always)]
995 fn static_type_id() -> $crate::TypeId {
996 $crate::TypeId::UNKNOWN
997 }
998
999 #[inline(always)]
1000 fn reserved_space() -> usize {
1001 $crate::type_id::SIZE_OF_REF_AND_TYPE
1002 }
1003
1004 const IS_POLYMORPHIC: bool = true;
1005
1006 const IS_SHARED_REF: bool = true;
1007
1008 const IS_WRAPPER: bool = true;
1009
1010 #[inline(always)]
1011 fn dynamic_type_id(
1012 value: &Self::Target,
1013 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
1014 Ok(Some(
1015 [<$trait_name ForyDispatch>]::any_ref(value.as_ref()).type_id(),
1016 ))
1017 }
1018 }
1019
1020 $crate::register_trait_type!(
1021 @codec
1022 [$vis]
1023 [<$trait_name ArcCodec>],
1024 [<$trait_name ArcSerializer>],
1025 std::sync::Arc<dyn $trait_name>
1026 );
1027 }
1028 };
1029
1030 (@codec [$vis:vis] $codec:ident, $provider:ty, $target:ty) => {
1031 #[allow(dead_code)]
1032 #[doc(hidden)]
1033 $vis struct $codec<const NULLABLE: bool, const TRACK_REF: bool>;
1034
1035 impl<const NULLABLE: bool, const TRACK_REF: bool> $crate::Serializer
1036 for $codec<NULLABLE, TRACK_REF>
1037 {
1038 type Target = $target;
1039
1040 #[inline(always)]
1041 fn write_data(
1042 value: &Self::Target,
1043 context: &mut $crate::WriteContext,
1044 ) -> Result<(), $crate::Error> {
1045 <$provider as $crate::Serializer>::write_data(value, context)
1046 }
1047
1048 #[inline(always)]
1049 fn read_data(
1050 context: &mut $crate::ReadContext,
1051 ) -> Result<Self::Target, $crate::Error> {
1052 <$provider as $crate::Serializer>::read_data(context)
1053 }
1054
1055 #[inline(always)]
1056 fn default_value(
1057 context: &mut $crate::ReadContext,
1058 ) -> Result<Self::Target, $crate::Error> {
1059 <$provider as $crate::Serializer>::default_value(context)
1060 }
1061
1062 #[inline(always)]
1063 fn write(
1064 value: &Self::Target,
1065 context: &mut $crate::WriteContext,
1066 ref_mode: $crate::RefMode,
1067 write_type_info: bool,
1068 ) -> Result<(), $crate::Error> {
1069 <$provider as $crate::Serializer>::write(
1070 value,
1071 context,
1072 ref_mode,
1073 write_type_info,
1074 )
1075 }
1076
1077 #[inline(always)]
1078 fn write_type_info_value(
1079 context: &mut $crate::WriteContext,
1080 target_type_id: std::any::TypeId,
1081 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
1082 <$provider as $crate::Serializer>::write_type_info_value(
1083 context,
1084 target_type_id,
1085 )
1086 }
1087
1088 #[inline(always)]
1089 fn write_with_type_info(
1090 value: &Self::Target,
1091 context: &mut $crate::WriteContext,
1092 ref_mode: $crate::RefMode,
1093 type_info: &std::rc::Rc<$crate::TypeInfo>,
1094 ) -> Result<(), $crate::Error> {
1095 <$provider as $crate::Serializer>::write_with_type_info(
1096 value,
1097 context,
1098 ref_mode,
1099 type_info,
1100 )
1101 }
1102
1103 #[inline(always)]
1104 fn read(
1105 context: &mut $crate::ReadContext,
1106 ref_mode: $crate::RefMode,
1107 read_type_info: bool,
1108 ) -> Result<Self::Target, $crate::Error> {
1109 <$provider as $crate::Serializer>::read(
1110 context,
1111 ref_mode,
1112 read_type_info,
1113 )
1114 }
1115
1116 #[inline(always)]
1117 fn read_with_type_info(
1118 context: &mut $crate::ReadContext,
1119 ref_mode: $crate::RefMode,
1120 type_info: &std::rc::Rc<$crate::TypeInfo>,
1121 ) -> Result<Self::Target, $crate::Error> {
1122 <$provider as $crate::Serializer>::read_with_type_info(
1123 context,
1124 ref_mode,
1125 type_info,
1126 )
1127 }
1128
1129 #[inline(always)]
1130 fn write_type_info(
1131 _context: &mut $crate::WriteContext,
1132 ) -> Result<(), $crate::Error> {
1133 Ok(())
1134 }
1135
1136 #[inline(always)]
1137 fn read_type_info(
1138 _context: &mut $crate::ReadContext,
1139 ) -> Result<(), $crate::Error> {
1140 Ok(())
1141 }
1142
1143 #[inline(always)]
1144 fn static_type_id() -> $crate::TypeId {
1145 $crate::TypeId::UNKNOWN
1146 }
1147
1148 #[inline(always)]
1149 fn reserved_space() -> usize {
1150 <$provider as $crate::Serializer>::reserved_space()
1151 }
1152
1153 const IS_OPTIONAL: bool = <$provider as $crate::Serializer>::IS_OPTIONAL;
1154
1155 const IS_POLYMORPHIC: bool = <$provider as $crate::Serializer>::IS_POLYMORPHIC;
1156
1157 const IS_SHARED_REF: bool = <$provider as $crate::Serializer>::IS_SHARED_REF;
1158
1159 const IS_WRAPPER: bool = <$provider as $crate::Serializer>::IS_WRAPPER;
1160
1161 const REQUIRES_SCOPED_ACCESS: bool =
1162 <$provider as $crate::Serializer>::REQUIRES_SCOPED_ACCESS;
1163
1164 #[inline(always)]
1165 fn dynamic_type_id(
1166 value: &Self::Target,
1167 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
1168 <$provider as $crate::Serializer>::dynamic_type_id(value)
1169 }
1170
1171 }
1172
1173 impl<const NULLABLE: bool, const TRACK_REF: bool>
1174 $crate::serializer::codec::Codec<$target>
1175 for $codec<NULLABLE, TRACK_REF>
1176 {
1177 #[inline(always)]
1178 fn field_type(
1179 _type_resolver: &$crate::TypeResolver,
1180 ) -> Result<$crate::meta::FieldType, $crate::Error> {
1181 Ok($crate::meta::FieldType::new_with_ref(
1182 $crate::TypeId::UNKNOWN as u32,
1183 NULLABLE,
1184 TRACK_REF,
1185 Vec::new(),
1186 ))
1187 }
1188
1189 #[inline(always)]
1190 fn field_reserved_space() -> usize {
1191 <$provider as $crate::Serializer>::reserved_space()
1192 + $crate::type_id::SIZE_OF_REF_AND_TYPE
1193 }
1194
1195 #[inline(always)]
1196 fn write_field(
1197 value: &$target,
1198 context: &mut $crate::WriteContext,
1199 ) -> Result<(), $crate::Error> {
1200 <$provider as $crate::Serializer>::write(
1201 value,
1202 context,
1203 if TRACK_REF {
1204 $crate::RefMode::Tracking
1205 } else if NULLABLE {
1206 $crate::RefMode::NullOnly
1207 } else {
1208 $crate::RefMode::None
1209 },
1210 true,
1211 )
1212 }
1213
1214 #[inline(always)]
1215 fn read_field(
1216 context: &mut $crate::ReadContext,
1217 ) -> Result<$target, $crate::Error> {
1218 <$provider as $crate::Serializer>::read(
1219 context,
1220 if TRACK_REF {
1221 $crate::RefMode::Tracking
1222 } else if NULLABLE {
1223 $crate::RefMode::NullOnly
1224 } else {
1225 $crate::RefMode::None
1226 },
1227 true,
1228 )
1229 }
1230
1231 #[inline(always)]
1232 fn read_field_with_type(
1233 context: &mut $crate::ReadContext,
1234 remote_field_type: &$crate::meta::FieldType,
1235 ) -> Result<$target, $crate::Error> {
1236 <$provider as $crate::Serializer>::read(
1237 context,
1238 $crate::serializer::codec::field_ref_mode(remote_field_type),
1239 true,
1240 )
1241 }
1242
1243 #[inline(always)]
1244 fn write_with_mode(
1245 value: &$target,
1246 context: &mut $crate::WriteContext,
1247 ref_mode: $crate::RefMode,
1248 write_type_info: bool,
1249 _has_generics: bool,
1250 ) -> Result<(), $crate::Error> {
1251 <$provider as $crate::Serializer>::write(
1252 value,
1253 context,
1254 ref_mode,
1255 write_type_info,
1256 )
1257 }
1258
1259 #[inline(always)]
1260 fn write_with_type_info(
1261 value: &$target,
1262 context: &mut $crate::WriteContext,
1263 ref_mode: $crate::RefMode,
1264 type_info: &std::rc::Rc<$crate::TypeInfo>,
1265 _has_generics: bool,
1266 ) -> Result<(), $crate::Error> {
1267 <$provider as $crate::Serializer>::write_with_type_info(
1268 value,
1269 context,
1270 ref_mode,
1271 type_info,
1272 )
1273 }
1274
1275 #[inline(always)]
1276 fn read_type_info_value(
1277 context: &mut $crate::ReadContext,
1278 ) -> Result<$crate::serializer::codec::CodecReadType, $crate::Error> {
1279 context
1280 .read_any_type_info()
1281 .map($crate::serializer::codec::CodecReadType::TypeInfo)
1282 }
1283 }
1284 };
1285}
1286
1287#[cfg(test)]
1288mod tests {
1289 use crate::{ForyObject, Serializer};
1290 use std::rc::Rc;
1291 use std::sync::Arc;
1292
1293 trait PrivateAnimal: ForyObject {}
1294
1295 struct PrivateDog;
1296
1297 impl PrivateAnimal for PrivateDog {}
1298
1299 register_trait_type!(PrivateAnimal, PrivateDog);
1300
1301 pub mod public_api {
1302 use crate::ForyObject;
1303
1304 pub trait PublicAnimal: ForyObject {}
1305
1306 pub struct PublicDog;
1307
1308 impl PublicAnimal for PublicDog {}
1309
1310 register_trait_type!(pub PublicAnimal, PublicDog);
1311
1312 pub trait SharedAnimal: ForyObject + Send + Sync {}
1313
1314 impl SharedAnimal for PublicDog {}
1315
1316 register_trait_type!(pub sync SharedAnimal, PublicDog);
1317 }
1318
1319 fn assert_target<S, T>()
1320 where
1321 S: Serializer<Target = T>,
1322 T: 'static,
1323 {
1324 }
1325
1326 #[test]
1327 fn trait_visibility_forms_compile() {
1328 assert_target::<PrivateAnimalRcSerializer, Rc<dyn PrivateAnimal>>();
1329 assert_target::<public_api::PublicAnimalRcSerializer, Rc<dyn public_api::PublicAnimal>>();
1330 assert_target::<public_api::SharedAnimalArcSerializer, Arc<dyn public_api::SharedAnimal>>();
1331 }
1332}