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 result = (|| {
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 result
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 result = (|| {
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 result
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 result = (|| {
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 result
625 }
626 $crate::RefFlag::RefValue => {
627 let ref_id = context.ref_reader.reserve_ref_id();
628 context.inc_depth()?;
629 let result = (|| {
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 let value = result?;
640 context.ref_reader.store_rc_ref_at(ref_id, value.clone());
641 Ok(value)
642 }
643 }
644 }
645
646 #[inline(always)]
647 fn read_with_type_info(
648 context: &mut $crate::ReadContext,
649 ref_mode: $crate::RefMode,
650 type_info: &std::rc::Rc<$crate::TypeInfo>,
651 ) -> Result<Self::Target, $crate::Error> {
652 let ref_flag = if ref_mode != $crate::RefMode::None {
653 context.ref_reader.read_ref_flag(&mut context.reader)?
654 } else {
655 $crate::RefFlag::NotNullValue
656 };
657 match ref_flag {
658 $crate::RefFlag::Null => {
659 Err([<$trait_name ForyDispatch>]::null_rc_value())
660 }
661 $crate::RefFlag::Ref => {
662 let ref_id =
663 context.ref_reader.read_ref_id(&mut context.reader)?;
664 context
665 .ref_reader
666 .get_rc_ref::<dyn $trait_name>(ref_id)
667 .ok_or_else(|| {
668 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
669 })
670 }
671 $crate::RefFlag::NotNullValue => {
672 context.inc_depth()?;
673 let result =
674 [<$trait_name ForyDispatch>]::read_rc(context, type_info);
675 context.dec_depth();
676 result
677 }
678 $crate::RefFlag::RefValue => {
679 let ref_id = context.ref_reader.reserve_ref_id();
680 context.inc_depth()?;
681 let result =
682 [<$trait_name ForyDispatch>]::read_rc(context, type_info);
683 context.dec_depth();
684 let value = result?;
685 context.ref_reader.store_rc_ref_at(ref_id, value.clone());
686 Ok(value)
687 }
688 }
689 }
690
691 #[inline(always)]
692 fn write_type_info(
693 _context: &mut $crate::WriteContext,
694 ) -> Result<(), $crate::Error> {
695 Ok(())
696 }
697
698 #[inline(always)]
699 fn read_type_info(
700 _context: &mut $crate::ReadContext,
701 ) -> Result<(), $crate::Error> {
702 Ok(())
703 }
704
705 #[inline(always)]
706 fn static_type_id() -> $crate::TypeId {
707 $crate::TypeId::UNKNOWN
708 }
709
710 #[inline(always)]
711 fn reserved_space() -> usize {
712 $crate::type_id::SIZE_OF_REF_AND_TYPE
713 }
714
715 const IS_POLYMORPHIC: bool = true;
716
717 const IS_SHARED_REF: bool = true;
718
719 const IS_WRAPPER: bool = true;
720
721 #[inline(always)]
722 fn dynamic_type_id(
723 value: &Self::Target,
724 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
725 Ok(Some(
726 [<$trait_name ForyDispatch>]::any_ref(value.as_ref()).type_id(),
727 ))
728 }
729 }
730
731 $crate::register_trait_type!(
732 @codec
733 [$vis]
734 [<$trait_name RcCodec>],
735 [<$trait_name RcSerializer>],
736 std::rc::Rc<dyn $trait_name>
737 );
738 }
739 };
740
741 (@arc [$vis:vis] $trait_name:ident, $($target:ty),+) => {
742 $crate::paste::paste! {
743 const _: () = {
744 fn assert_sync<T: ?Sized + Send + Sync>() {}
745 let _ = assert_sync::<dyn $trait_name>;
746 $(let _ = assert_sync::<$target>;)+
747 };
748
749 #[allow(dead_code)]
750 impl [<$trait_name ForyDispatch>] {
751 #[cold]
752 #[inline(never)]
753 fn null_arc_value() -> $crate::Error {
754 $crate::Error::invalid_ref(concat!(
755 "Arc<dyn ",
756 stringify!($trait_name),
757 "> cannot be null",
758 ))
759 }
760
761 #[cold]
762 #[inline(never)]
763 fn missing_arc_metadata() -> $crate::Error {
764 $crate::Error::invalid_data(concat!(
765 "Arc<dyn ",
766 stringify!($trait_name),
767 "> requires concrete type metadata",
768 ))
769 }
770
771 #[inline(always)]
772 fn read_arc(
773 context: &mut $crate::ReadContext,
774 type_info: &std::rc::Rc<$crate::TypeInfo>,
775 ) -> Result<std::sync::Arc<dyn $trait_name>, $crate::Error> {
776 let target_type_id = Self::target_id(type_info)?;
777 $crate::serializer::any::check_erased_target_type(type_info)?;
778 $(
779 if target_type_id == std::any::TypeId::of::<$target>() {
780 let erased = type_info
781 .get_harness()
782 .read_arc_any(context, type_info)?;
783 let concrete = erased.downcast::<$target>().map_err(|value| {
784 Self::downcast(target_type_id, value.as_ref().type_id())
785 })?;
786 let value: std::sync::Arc<dyn $trait_name> = concrete;
787 return Ok(value);
788 }
789 )+
790 Err(Self::unlisted(target_type_id))
791 }
792 }
793
794 #[allow(dead_code)]
795 #[doc = concat!("Serializer for `Arc<dyn ", stringify!($trait_name), ">`.")]
796 $vis struct [<$trait_name ArcSerializer>](std::marker::PhantomData<()>);
797
798 impl $crate::Serializer for [<$trait_name ArcSerializer>] {
799 type Target = std::sync::Arc<dyn $trait_name>;
800 #[inline(always)]
801 fn write_data(
802 value: &Self::Target,
803 context: &mut $crate::WriteContext,
804 ) -> Result<(), $crate::Error> {
805 [<$trait_name ForyDispatch>]::write_data(
806 value.as_ref(),
807 context,
808 false,
809 )
810 }
811
812 #[cold]
813 #[inline(never)]
814 fn read_data(
815 _context: &mut $crate::ReadContext,
816 ) -> Result<Self::Target, $crate::Error> {
817 Err($crate::Error::not_allowed(concat!(
818 "Arc<dyn ",
819 stringify!($trait_name),
820 "> requires concrete type metadata",
821 )))
822 }
823
824 #[inline(always)]
825 fn write_type_info_value(
826 context: &mut $crate::WriteContext,
827 target_type_id: std::any::TypeId,
828 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
829 [<$trait_name ForyDispatch>]::write_type_info_value(
830 context,
831 target_type_id,
832 )
833 }
834
835 #[inline(always)]
836 fn write_with_type_info(
837 value: &Self::Target,
838 context: &mut $crate::WriteContext,
839 ref_mode: $crate::RefMode,
840 type_info: &std::rc::Rc<$crate::TypeInfo>,
841 ) -> Result<(), $crate::Error> {
842 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
843 [<$trait_name ForyDispatch>]::check_type_info(any.type_id(), type_info)?;
844 if ref_mode != $crate::RefMode::None
845 && context
846 .ref_writer
847 .try_write_arc_ref(&mut context.writer, value)
848 {
849 return Ok(());
850 }
851 [<$trait_name ForyDispatch>]::write_harness(
852 any,
853 context,
854 type_info,
855 )
856 }
857
858 #[inline(always)]
859 fn write(
860 value: &Self::Target,
861 context: &mut $crate::WriteContext,
862 ref_mode: $crate::RefMode,
863 write_type_info: bool,
864 ) -> Result<(), $crate::Error> {
865 let any = [<$trait_name ForyDispatch>]::checked_any(value.as_ref())?;
866 if ref_mode != $crate::RefMode::None
867 && context
868 .ref_writer
869 .try_write_arc_ref(&mut context.writer, value)
870 {
871 return Ok(());
872 }
873 [<$trait_name ForyDispatch>]::write_checked(
874 any,
875 context,
876 write_type_info,
877 )
878 }
879
880 #[inline(always)]
881 fn read(
882 context: &mut $crate::ReadContext,
883 ref_mode: $crate::RefMode,
884 read_type_info: bool,
885 ) -> Result<Self::Target, $crate::Error> {
886 let ref_flag = if ref_mode != $crate::RefMode::None {
887 context.ref_reader.read_ref_flag(&mut context.reader)?
888 } else {
889 $crate::RefFlag::NotNullValue
890 };
891 match ref_flag {
892 $crate::RefFlag::Null => {
893 Err([<$trait_name ForyDispatch>]::null_arc_value())
894 }
895 $crate::RefFlag::Ref => {
896 let ref_id =
897 context.ref_reader.read_ref_id(&mut context.reader)?;
898 context
899 .ref_reader
900 .get_arc_ref::<dyn $trait_name>(ref_id)
901 .ok_or_else(|| {
902 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
903 })
904 }
905 $crate::RefFlag::NotNullValue => {
906 context.inc_depth()?;
907 let result = (|| {
908 if !read_type_info {
909 return Err(
910 [<$trait_name ForyDispatch>]::missing_arc_metadata()
911 );
912 }
913 let type_info = context.read_any_type_info()?;
914 [<$trait_name ForyDispatch>]::read_arc(context, &type_info)
915 })();
916 context.dec_depth();
917 result
918 }
919 $crate::RefFlag::RefValue => {
920 let ref_id = context.ref_reader.reserve_ref_id();
921 context.inc_depth()?;
922 let result = (|| {
923 if !read_type_info {
924 return Err(
925 [<$trait_name ForyDispatch>]::missing_arc_metadata()
926 );
927 }
928 let type_info = context.read_any_type_info()?;
929 [<$trait_name ForyDispatch>]::read_arc(context, &type_info)
930 })();
931 context.dec_depth();
932 let value = result?;
933 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
934 Ok(value)
935 }
936 }
937 }
938
939 #[inline(always)]
940 fn read_with_type_info(
941 context: &mut $crate::ReadContext,
942 ref_mode: $crate::RefMode,
943 type_info: &std::rc::Rc<$crate::TypeInfo>,
944 ) -> Result<Self::Target, $crate::Error> {
945 let ref_flag = if ref_mode != $crate::RefMode::None {
946 context.ref_reader.read_ref_flag(&mut context.reader)?
947 } else {
948 $crate::RefFlag::NotNullValue
949 };
950 match ref_flag {
951 $crate::RefFlag::Null => {
952 Err([<$trait_name ForyDispatch>]::null_arc_value())
953 }
954 $crate::RefFlag::Ref => {
955 let ref_id =
956 context.ref_reader.read_ref_id(&mut context.reader)?;
957 context
958 .ref_reader
959 .get_arc_ref::<dyn $trait_name>(ref_id)
960 .ok_or_else(|| {
961 [<$trait_name ForyDispatch>]::missing_ref(ref_id)
962 })
963 }
964 $crate::RefFlag::NotNullValue => {
965 context.inc_depth()?;
966 let result =
967 [<$trait_name ForyDispatch>]::read_arc(context, type_info);
968 context.dec_depth();
969 result
970 }
971 $crate::RefFlag::RefValue => {
972 let ref_id = context.ref_reader.reserve_ref_id();
973 context.inc_depth()?;
974 let result =
975 [<$trait_name ForyDispatch>]::read_arc(context, type_info);
976 context.dec_depth();
977 let value = result?;
978 context.ref_reader.store_arc_ref_at(ref_id, value.clone());
979 Ok(value)
980 }
981 }
982 }
983
984 #[inline(always)]
985 fn write_type_info(
986 _context: &mut $crate::WriteContext,
987 ) -> Result<(), $crate::Error> {
988 Ok(())
989 }
990
991 #[inline(always)]
992 fn read_type_info(
993 _context: &mut $crate::ReadContext,
994 ) -> Result<(), $crate::Error> {
995 Ok(())
996 }
997
998 #[inline(always)]
999 fn static_type_id() -> $crate::TypeId {
1000 $crate::TypeId::UNKNOWN
1001 }
1002
1003 #[inline(always)]
1004 fn reserved_space() -> usize {
1005 $crate::type_id::SIZE_OF_REF_AND_TYPE
1006 }
1007
1008 const IS_POLYMORPHIC: bool = true;
1009
1010 const IS_SHARED_REF: bool = true;
1011
1012 const IS_WRAPPER: bool = true;
1013
1014 #[inline(always)]
1015 fn dynamic_type_id(
1016 value: &Self::Target,
1017 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
1018 Ok(Some(
1019 [<$trait_name ForyDispatch>]::any_ref(value.as_ref()).type_id(),
1020 ))
1021 }
1022 }
1023
1024 $crate::register_trait_type!(
1025 @codec
1026 [$vis]
1027 [<$trait_name ArcCodec>],
1028 [<$trait_name ArcSerializer>],
1029 std::sync::Arc<dyn $trait_name>
1030 );
1031 }
1032 };
1033
1034 (@codec [$vis:vis] $codec:ident, $provider:ty, $target:ty) => {
1035 #[allow(dead_code)]
1036 #[doc(hidden)]
1037 $vis struct $codec<const NULLABLE: bool, const TRACK_REF: bool>;
1038
1039 impl<const NULLABLE: bool, const TRACK_REF: bool> $crate::Serializer
1040 for $codec<NULLABLE, TRACK_REF>
1041 {
1042 type Target = $target;
1043
1044 #[inline(always)]
1045 fn write_data(
1046 value: &Self::Target,
1047 context: &mut $crate::WriteContext,
1048 ) -> Result<(), $crate::Error> {
1049 <$provider as $crate::Serializer>::write_data(value, context)
1050 }
1051
1052 #[inline(always)]
1053 fn read_data(
1054 context: &mut $crate::ReadContext,
1055 ) -> Result<Self::Target, $crate::Error> {
1056 <$provider as $crate::Serializer>::read_data(context)
1057 }
1058
1059 #[inline(always)]
1060 fn default_value(
1061 context: &mut $crate::ReadContext,
1062 ) -> Result<Self::Target, $crate::Error> {
1063 <$provider as $crate::Serializer>::default_value(context)
1064 }
1065
1066 #[inline(always)]
1067 fn write(
1068 value: &Self::Target,
1069 context: &mut $crate::WriteContext,
1070 ref_mode: $crate::RefMode,
1071 write_type_info: bool,
1072 ) -> Result<(), $crate::Error> {
1073 <$provider as $crate::Serializer>::write(
1074 value,
1075 context,
1076 ref_mode,
1077 write_type_info,
1078 )
1079 }
1080
1081 #[inline(always)]
1082 fn write_type_info_value(
1083 context: &mut $crate::WriteContext,
1084 target_type_id: std::any::TypeId,
1085 ) -> Result<std::rc::Rc<$crate::TypeInfo>, $crate::Error> {
1086 <$provider as $crate::Serializer>::write_type_info_value(
1087 context,
1088 target_type_id,
1089 )
1090 }
1091
1092 #[inline(always)]
1093 fn write_with_type_info(
1094 value: &Self::Target,
1095 context: &mut $crate::WriteContext,
1096 ref_mode: $crate::RefMode,
1097 type_info: &std::rc::Rc<$crate::TypeInfo>,
1098 ) -> Result<(), $crate::Error> {
1099 <$provider as $crate::Serializer>::write_with_type_info(
1100 value,
1101 context,
1102 ref_mode,
1103 type_info,
1104 )
1105 }
1106
1107 #[inline(always)]
1108 fn read(
1109 context: &mut $crate::ReadContext,
1110 ref_mode: $crate::RefMode,
1111 read_type_info: bool,
1112 ) -> Result<Self::Target, $crate::Error> {
1113 <$provider as $crate::Serializer>::read(
1114 context,
1115 ref_mode,
1116 read_type_info,
1117 )
1118 }
1119
1120 #[inline(always)]
1121 fn read_with_type_info(
1122 context: &mut $crate::ReadContext,
1123 ref_mode: $crate::RefMode,
1124 type_info: &std::rc::Rc<$crate::TypeInfo>,
1125 ) -> Result<Self::Target, $crate::Error> {
1126 <$provider as $crate::Serializer>::read_with_type_info(
1127 context,
1128 ref_mode,
1129 type_info,
1130 )
1131 }
1132
1133 #[inline(always)]
1134 fn write_type_info(
1135 _context: &mut $crate::WriteContext,
1136 ) -> Result<(), $crate::Error> {
1137 Ok(())
1138 }
1139
1140 #[inline(always)]
1141 fn read_type_info(
1142 _context: &mut $crate::ReadContext,
1143 ) -> Result<(), $crate::Error> {
1144 Ok(())
1145 }
1146
1147 #[inline(always)]
1148 fn static_type_id() -> $crate::TypeId {
1149 $crate::TypeId::UNKNOWN
1150 }
1151
1152 #[inline(always)]
1153 fn reserved_space() -> usize {
1154 <$provider as $crate::Serializer>::reserved_space()
1155 }
1156
1157 const IS_OPTIONAL: bool = <$provider as $crate::Serializer>::IS_OPTIONAL;
1158
1159 const IS_POLYMORPHIC: bool = <$provider as $crate::Serializer>::IS_POLYMORPHIC;
1160
1161 const IS_SHARED_REF: bool = <$provider as $crate::Serializer>::IS_SHARED_REF;
1162
1163 const IS_WRAPPER: bool = <$provider as $crate::Serializer>::IS_WRAPPER;
1164
1165 const REQUIRES_SCOPED_ACCESS: bool =
1166 <$provider as $crate::Serializer>::REQUIRES_SCOPED_ACCESS;
1167
1168 #[inline(always)]
1169 fn dynamic_type_id(
1170 value: &Self::Target,
1171 ) -> Result<Option<std::any::TypeId>, $crate::Error> {
1172 <$provider as $crate::Serializer>::dynamic_type_id(value)
1173 }
1174
1175 }
1176
1177 impl<const NULLABLE: bool, const TRACK_REF: bool>
1178 $crate::serializer::codec::Codec<$target>
1179 for $codec<NULLABLE, TRACK_REF>
1180 {
1181 #[inline(always)]
1182 fn field_type(
1183 _type_resolver: &$crate::TypeResolver,
1184 ) -> Result<$crate::meta::FieldType, $crate::Error> {
1185 Ok($crate::meta::FieldType::new_with_ref(
1186 $crate::TypeId::UNKNOWN as u32,
1187 NULLABLE,
1188 TRACK_REF,
1189 Vec::new(),
1190 ))
1191 }
1192
1193 #[inline(always)]
1194 fn field_reserved_space() -> usize {
1195 <$provider as $crate::Serializer>::reserved_space()
1196 + $crate::type_id::SIZE_OF_REF_AND_TYPE
1197 }
1198
1199 #[inline(always)]
1200 fn write_field(
1201 value: &$target,
1202 context: &mut $crate::WriteContext,
1203 ) -> Result<(), $crate::Error> {
1204 <$provider as $crate::Serializer>::write(
1205 value,
1206 context,
1207 if TRACK_REF {
1208 $crate::RefMode::Tracking
1209 } else if NULLABLE {
1210 $crate::RefMode::NullOnly
1211 } else {
1212 $crate::RefMode::None
1213 },
1214 true,
1215 )
1216 }
1217
1218 #[inline(always)]
1219 fn read_field(
1220 context: &mut $crate::ReadContext,
1221 ) -> Result<$target, $crate::Error> {
1222 <$provider as $crate::Serializer>::read(
1223 context,
1224 if TRACK_REF {
1225 $crate::RefMode::Tracking
1226 } else if NULLABLE {
1227 $crate::RefMode::NullOnly
1228 } else {
1229 $crate::RefMode::None
1230 },
1231 true,
1232 )
1233 }
1234
1235 #[inline(always)]
1236 fn read_field_with_type(
1237 context: &mut $crate::ReadContext,
1238 remote_field_type: &$crate::meta::FieldType,
1239 ) -> Result<$target, $crate::Error> {
1240 <$provider as $crate::Serializer>::read(
1241 context,
1242 $crate::serializer::codec::field_ref_mode(remote_field_type),
1243 true,
1244 )
1245 }
1246
1247 #[inline(always)]
1248 fn write_with_mode(
1249 value: &$target,
1250 context: &mut $crate::WriteContext,
1251 ref_mode: $crate::RefMode,
1252 write_type_info: bool,
1253 _has_generics: bool,
1254 ) -> Result<(), $crate::Error> {
1255 <$provider as $crate::Serializer>::write(
1256 value,
1257 context,
1258 ref_mode,
1259 write_type_info,
1260 )
1261 }
1262
1263 #[inline(always)]
1264 fn write_with_type_info(
1265 value: &$target,
1266 context: &mut $crate::WriteContext,
1267 ref_mode: $crate::RefMode,
1268 type_info: &std::rc::Rc<$crate::TypeInfo>,
1269 _has_generics: bool,
1270 ) -> Result<(), $crate::Error> {
1271 <$provider as $crate::Serializer>::write_with_type_info(
1272 value,
1273 context,
1274 ref_mode,
1275 type_info,
1276 )
1277 }
1278
1279 #[inline(always)]
1280 fn read_type_info_value(
1281 context: &mut $crate::ReadContext,
1282 ) -> Result<$crate::serializer::codec::CodecReadType, $crate::Error> {
1283 context
1284 .read_any_type_info()
1285 .map($crate::serializer::codec::CodecReadType::TypeInfo)
1286 }
1287 }
1288 };
1289}
1290
1291#[cfg(test)]
1292mod tests {
1293 use crate::{ForyObject, Serializer};
1294 use std::rc::Rc;
1295 use std::sync::Arc;
1296
1297 trait PrivateAnimal: ForyObject {}
1298
1299 struct PrivateDog;
1300
1301 impl PrivateAnimal for PrivateDog {}
1302
1303 register_trait_type!(PrivateAnimal, PrivateDog);
1304
1305 pub mod public_api {
1306 use crate::ForyObject;
1307
1308 pub trait PublicAnimal: ForyObject {}
1309
1310 pub struct PublicDog;
1311
1312 impl PublicAnimal for PublicDog {}
1313
1314 register_trait_type!(pub PublicAnimal, PublicDog);
1315
1316 pub trait SharedAnimal: ForyObject + Send + Sync {}
1317
1318 impl SharedAnimal for PublicDog {}
1319
1320 register_trait_type!(pub sync SharedAnimal, PublicDog);
1321 }
1322
1323 fn assert_target<S, T>()
1324 where
1325 S: Serializer<Target = T>,
1326 T: 'static,
1327 {
1328 }
1329
1330 #[test]
1331 fn trait_visibility_forms_compile() {
1332 assert_target::<PrivateAnimalRcSerializer, Rc<dyn PrivateAnimal>>();
1333 assert_target::<public_api::PublicAnimalRcSerializer, Rc<dyn public_api::PublicAnimal>>();
1334 assert_target::<public_api::SharedAnimalArcSerializer, Arc<dyn public_api::SharedAnimal>>();
1335 }
1336}