1use crate::{
2 PtrConstWide, PtrMutWide, PtrUninitWide, TypedPtrUninit,
3 ptr::{PtrConst, PtrMut, PtrUninit},
4};
5use bitflags::bitflags;
6use core::{cmp::Ordering, marker::PhantomData, mem};
7
8use crate::Shape;
9
10use super::UnsizedError;
11
12pub type TypeNameFn = fn(f: &mut core::fmt::Formatter, opts: TypeNameOpts) -> core::fmt::Result;
18
19#[derive(Clone, Copy)]
21pub struct TypeNameOpts {
22 pub recurse_ttl: isize,
26}
27
28impl Default for TypeNameOpts {
29 #[inline]
30 fn default() -> Self {
31 Self { recurse_ttl: -1 }
32 }
33}
34
35impl TypeNameOpts {
36 #[inline]
38 pub fn none() -> Self {
39 Self { recurse_ttl: 0 }
40 }
41
42 #[inline]
44 pub fn one() -> Self {
45 Self { recurse_ttl: 1 }
46 }
47
48 #[inline]
50 pub fn infinite() -> Self {
51 Self { recurse_ttl: -1 }
52 }
53
54 #[inline]
62 pub fn for_children(&self) -> Option<Self> {
63 match self.recurse_ttl.cmp(&0) {
64 Ordering::Greater => Some(Self {
65 recurse_ttl: self.recurse_ttl - 1,
66 }),
67 Ordering::Less => Some(Self {
68 recurse_ttl: self.recurse_ttl,
69 }),
70 Ordering::Equal => None,
71 }
72 }
73}
74
75pub type InvariantsFn = for<'mem> unsafe fn(value: PtrConst<'mem>) -> bool;
83
84pub type InvariantsFnWide = for<'mem> unsafe fn(value: PtrConstWide<'mem>) -> bool;
90
91pub type InvariantsFnTyped<T> = fn(value: &T) -> bool;
93
94pub type DropInPlaceFn = for<'mem> unsafe fn(value: PtrMut<'mem>) -> PtrUninit<'mem>;
104
105pub type DropInPlaceFnWide = for<'mem> unsafe fn(value: PtrMutWide<'mem>) -> PtrUninitWide<'mem>;
113
114pub type CloneIntoFn =
122 for<'src, 'dst> unsafe fn(source: PtrConst<'src>, target: PtrUninit<'dst>) -> PtrMut<'dst>;
123pub type CloneIntoFnTyped<T> =
125 for<'src, 'dst> fn(source: &'src T, target: TypedPtrUninit<'dst, T>) -> &'dst mut T;
126
127pub type DefaultInPlaceFn = for<'mem> unsafe fn(target: PtrUninit<'mem>) -> PtrMut<'mem>;
134pub type DefaultInPlaceFnTyped<T> = for<'mem> fn(target: TypedPtrUninit<'mem, T>) -> &'mem mut T;
136
137pub type ParseFn =
149 for<'mem> unsafe fn(s: &str, target: PtrUninit<'mem>) -> Result<PtrMut<'mem>, ParseError>;
150
151pub type ParseFnTyped<T> =
155 for<'mem> fn(s: &str, target: TypedPtrUninit<'mem, T>) -> Result<&'mem mut T, ParseError>;
156
157#[derive(Debug)]
159pub enum ParseError {
160 Generic(&'static str),
162}
163
164impl core::fmt::Display for ParseError {
165 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
166 match self {
167 ParseError::Generic(msg) => write!(f, "Parse failed: {msg}"),
168 }
169 }
170}
171
172impl core::error::Error for ParseError {}
173
174pub type TryFromFn = for<'src, 'mem, 'shape> unsafe fn(
182 source: PtrConst<'src>,
183 source_shape: &'static Shape,
184 target: PtrUninit<'mem>,
185) -> Result<PtrMut<'mem>, TryFromError>;
186
187pub type TryFromFnTyped<T> = for<'src, 'mem, 'shape> fn(
189 source: &'src T,
190 source_shape: &'static Shape,
191 target: TypedPtrUninit<'mem, T>,
192) -> Result<&'mem mut T, TryFromError>;
193
194#[derive(Debug, PartialEq, Clone)]
196pub enum TryFromError {
197 Generic(&'static str),
199
200 Unimplemented,
202
203 UnsupportedSourceShape {
205 src_shape: &'static Shape,
207
208 expected: &'static [&'static Shape],
210 },
211
212 Unsized,
214}
215
216impl core::fmt::Display for TryFromError {
217 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
218 match self {
219 TryFromError::Generic(msg) => write!(f, "{msg}"),
220 TryFromError::Unimplemented => write!(
221 f,
222 "Shape doesn't implement any conversions (no try_from function)",
223 ),
224 TryFromError::UnsupportedSourceShape {
225 src_shape: source_shape,
226 expected,
227 } => {
228 write!(f, "Incompatible types: {source_shape} (expected one of ")?;
229 for (index, sh) in expected.iter().enumerate() {
230 if index > 0 {
231 write!(f, ", ")?;
232 }
233 write!(f, "{sh}")?;
234 }
235 write!(f, ")")?;
236 Ok(())
237 }
238 TryFromError::Unsized => write!(f, "Unsized type"),
239 }
240 }
241}
242
243impl core::error::Error for TryFromError {}
244
245impl From<UnsizedError> for TryFromError {
246 #[inline]
247 fn from(_value: UnsizedError) -> Self {
248 Self::Unsized
249 }
250}
251
252pub type TryIntoInnerFn = for<'src, 'dst> unsafe fn(
267 src_ptr: PtrMut<'src>,
268 dst: PtrUninit<'dst>,
269) -> Result<PtrMut<'dst>, TryIntoInnerError>;
270pub type TryIntoInnerFnTyped<T> = for<'src, 'dst> fn(
275 src_ptr: &'src T,
276 dst: TypedPtrUninit<'dst, T>,
277) -> Result<&'dst mut T, TryIntoInnerError>;
278
279#[derive(Debug, Clone, PartialEq, Eq)]
282pub enum TryIntoInnerError {
283 Unavailable,
286 Other(&'static str),
288}
289
290impl core::fmt::Display for TryIntoInnerError {
291 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
292 match self {
293 TryIntoInnerError::Unavailable => {
294 write!(f, "inner value is unavailable for extraction")
295 }
296 TryIntoInnerError::Other(msg) => write!(f, "{msg}"),
297 }
298 }
299}
300
301impl core::error::Error for TryIntoInnerError {}
302
303pub type TryBorrowInnerFn =
316 for<'src> unsafe fn(src_ptr: PtrConst<'src>) -> Result<PtrConst<'src>, TryBorrowInnerError>;
317
318pub type TryBorrowInnerFnWide =
320 for<'src> unsafe fn(
321 src_ptr: PtrConstWide<'src>,
322 ) -> Result<PtrConstWide<'src>, TryBorrowInnerError>;
323
324pub type TryBorrowInnerFnTyped<T> =
329 for<'src> fn(src_ptr: &'src T) -> Result<&'src T, TryBorrowInnerError>;
330
331#[derive(Debug, Clone, PartialEq, Eq)]
334pub enum TryBorrowInnerError {
335 Unavailable,
338 Other(&'static str),
341}
342
343impl core::fmt::Display for TryBorrowInnerError {
344 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
345 match self {
346 TryBorrowInnerError::Unavailable => {
347 write!(f, "inner value is unavailable for borrowing")
348 }
349 TryBorrowInnerError::Other(msg) => {
350 write!(f, "{msg}")
351 }
352 }
353 }
354}
355
356impl core::error::Error for TryBorrowInnerError {}
357
358pub type PartialEqFn = for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> bool;
366pub type PartialEqFnWide =
372 for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> bool;
373pub type PartialEqFnTyped<T> = fn(left: &T, right: &T) -> bool;
375
376pub type PartialOrdFn =
382 for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> Option<Ordering>;
383pub type PartialOrdFnWide =
389 for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> Option<Ordering>;
390pub type PartialOrdFnTyped<T> = fn(left: &T, right: &T) -> Option<Ordering>;
392
393pub type CmpFn = for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> Ordering;
399pub type CmpFnWide =
405 for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> Ordering;
406pub type CmpFnTyped<T> = fn(left: &T, right: &T) -> Ordering;
408
409pub type HashFn = for<'mem> unsafe fn(
418 value: PtrConst<'mem>,
419 hasher_this: PtrMut<'mem>,
421 hasher_write_fn: HasherWriteFn,
422);
423
424pub type HashFnWide = for<'mem> unsafe fn(
431 value: PtrConstWide<'mem>,
432
433 hasher_this: PtrMut<'mem>,
435 hasher_write_fn: HasherWriteFn,
436);
437
438pub type HashFnTyped<T> =
440 for<'mem> fn(value: &'mem T, hasher_this: PtrMut<'mem>, hasher_write_fn: HasherWriteFn);
441
442pub type HasherWriteFn = for<'mem> unsafe fn(hasher_self: PtrMut<'mem>, bytes: &[u8]);
448pub type HasherWriteFnTyped<T> = for<'mem> fn(hasher_self: &'mem mut T, bytes: &[u8]);
450
451pub struct HasherProxy<'a> {
455 hasher_this: PtrMut<'a>,
456 hasher_write_fn: HasherWriteFn,
457}
458
459impl<'a> HasherProxy<'a> {
460 #[inline]
467 pub unsafe fn new(hasher_this: PtrMut<'a>, hasher_write_fn: HasherWriteFn) -> Self {
468 Self {
469 hasher_this,
470 hasher_write_fn,
471 }
472 }
473}
474
475impl core::hash::Hasher for HasherProxy<'_> {
476 fn finish(&self) -> u64 {
477 unimplemented!("finish is not needed for this implementation")
478 }
479 #[inline]
480 fn write(&mut self, bytes: &[u8]) {
481 unsafe { (self.hasher_write_fn)(self.hasher_this, bytes) }
482 }
483}
484
485bitflags! {
488 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
499 pub struct MarkerTraits: u8 {
500 const EQ = 1 << 0;
502 const SEND = 1 << 1;
506 const SYNC = 1 << 2;
510 const COPY = 1 << 3;
512 const UNPIN = 1 << 4;
514 const UNWIND_SAFE = 1 << 5;
518 const REF_UNWIND_SAFE = 1 << 6;
522 }
523}
524
525pub type DisplayFn =
535 for<'mem> unsafe fn(value: PtrConst<'mem>, f: &mut core::fmt::Formatter) -> core::fmt::Result;
536
537pub type DisplayFnWide = for<'mem> unsafe fn(
545 value: PtrConstWide<'mem>,
546 f: &mut core::fmt::Formatter,
547) -> core::fmt::Result;
548
549pub type DisplayFnTyped<T> = fn(value: &T, f: &mut core::fmt::Formatter) -> core::fmt::Result;
553
554pub type DebugFn =
557 for<'mem> unsafe fn(value: PtrConst<'mem>, f: &mut core::fmt::Formatter) -> core::fmt::Result;
558
559pub type DebugFnWide = for<'mem> unsafe fn(
562 value: PtrConstWide<'mem>,
563 f: &mut core::fmt::Formatter,
564) -> core::fmt::Result;
565
566pub type DebugFnTyped<T> = fn(value: &T, f: &mut core::fmt::Formatter) -> core::fmt::Result;
569
570#[derive(Debug, Clone, Copy)]
577#[repr(C)]
578pub enum ValueVTable {
579 Sized(ValueVTableSized),
581 Unsized(ValueVTableUnsized),
583}
584
585#[derive(Debug, Clone, Copy)]
587#[repr(C)]
588pub struct ValueVTableSized {
589 pub type_name: TypeNameFn,
591 pub marker_traits: fn() -> MarkerTraits,
595
596 pub drop_in_place: fn() -> Option<DropInPlaceFn>,
598
599 pub invariants: fn() -> Option<InvariantsFn>,
601
602 pub display: fn() -> Option<DisplayFn>,
604
605 pub debug: fn() -> Option<DebugFn>,
607
608 pub default_in_place: fn() -> Option<DefaultInPlaceFn>,
610
611 pub clone_into: fn() -> Option<CloneIntoFn>,
613
614 pub partial_eq: fn() -> Option<PartialEqFn>,
616
617 pub partial_ord: fn() -> Option<PartialOrdFn>,
619
620 pub ord: fn() -> Option<CmpFn>,
622
623 pub hash: fn() -> Option<HashFn>,
625
626 pub parse: fn() -> Option<ParseFn>,
628
629 pub try_from: fn() -> Option<TryFromFn>,
641
642 pub try_into_inner: fn() -> Option<TryIntoInnerFn>,
647
648 pub try_borrow_inner: fn() -> Option<TryBorrowInnerFn>,
652}
653
654#[derive(Debug, Clone, Copy)]
656#[repr(C)]
657pub struct ValueVTableUnsized {
658 pub type_name: TypeNameFn,
660 pub marker_traits: fn() -> MarkerTraits,
664
665 pub drop_in_place: fn() -> Option<DropInPlaceFnWide>,
667
668 pub invariants: fn() -> Option<InvariantsFnWide>,
670
671 pub display: fn() -> Option<DisplayFnWide>,
673
674 pub debug: fn() -> Option<DebugFnWide>,
676
677 pub partial_eq: fn() -> Option<PartialEqFnWide>,
679
680 pub partial_ord: fn() -> Option<PartialOrdFnWide>,
682
683 pub ord: fn() -> Option<CmpFnWide>,
685
686 pub hash: fn() -> Option<HashFnWide>,
688
689 pub try_borrow_inner: fn() -> Option<TryBorrowInnerFnWide>,
693}
694
695macro_rules! has_fn {
696 ($self:expr, $name:tt) => {
697 match $self {
698 ValueVTable::Sized(inner) => (inner.$name)().is_some(),
699 ValueVTable::Unsized(inner) => (inner.$name)().is_some(),
700 }
701 };
702}
703
704macro_rules! has_fn_sized {
705 ($self:expr, $name:tt) => {
706 match $self {
707 ValueVTable::Sized(inner) => (inner.$name)().is_some(),
708 ValueVTable::Unsized(_) => false,
709 }
710 };
711}
712
713impl ValueVTable {
714 pub const fn sized(&self) -> Option<&ValueVTableSized> {
721 match self {
722 ValueVTable::Sized(inner) => Some(inner),
723 ValueVTable::Unsized(_) => None,
724 }
725 }
726
727 pub const fn sized_mut(&mut self) -> Option<&mut ValueVTableSized> {
734 match self {
735 ValueVTable::Sized(inner) => Some(inner),
736 ValueVTable::Unsized(_) => None,
737 }
738 }
739
740 pub const fn r#unsized(&self) -> Option<&ValueVTableUnsized> {
747 match self {
748 ValueVTable::Sized(_) => None,
749 ValueVTable::Unsized(inner) => Some(inner),
750 }
751 }
752
753 #[inline]
755 pub fn marker_traits(&self) -> MarkerTraits {
756 match self {
757 ValueVTable::Sized(inner) => (inner.marker_traits)(),
758 ValueVTable::Unsized(inner) => (inner.marker_traits)(),
759 }
760 }
761
762 #[inline]
764 pub const fn type_name(&self) -> TypeNameFn {
765 match self {
766 ValueVTable::Sized(inner) => inner.type_name,
767 ValueVTable::Unsized(inner) => inner.type_name,
768 }
769 }
770
771 #[inline]
773 pub fn is_eq(&self) -> bool {
774 self.marker_traits().contains(MarkerTraits::EQ)
775 }
776
777 #[inline]
779 pub fn is_send(&self) -> bool {
780 self.marker_traits().contains(MarkerTraits::SEND)
781 }
782
783 #[inline]
785 pub fn is_sync(&self) -> bool {
786 self.marker_traits().contains(MarkerTraits::SYNC)
787 }
788
789 #[inline]
791 pub fn is_copy(&self) -> bool {
792 self.marker_traits().contains(MarkerTraits::COPY)
793 }
794
795 #[inline]
797 pub fn is_unpin(&self) -> bool {
798 self.marker_traits().contains(MarkerTraits::UNPIN)
799 }
800
801 #[inline]
803 pub fn is_unwind_safe(&self) -> bool {
804 self.marker_traits().contains(MarkerTraits::UNWIND_SAFE)
805 }
806
807 #[inline]
809 pub fn is_ref_unwind_safe(&self) -> bool {
810 self.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE)
811 }
812
813 #[inline]
815 pub fn has_display(&self) -> bool {
816 has_fn!(self, display)
817 }
818
819 #[inline]
821 pub fn has_debug(&self) -> bool {
822 has_fn!(self, debug)
823 }
824
825 #[inline]
827 pub fn has_partial_eq(&self) -> bool {
828 has_fn!(self, partial_eq)
829 }
830
831 #[inline]
833 pub fn has_partial_ord(&self) -> bool {
834 has_fn!(self, partial_ord)
835 }
836
837 #[inline]
839 pub fn has_ord(&self) -> bool {
840 has_fn!(self, ord)
841 }
842
843 #[inline]
845 pub fn has_hash(&self) -> bool {
846 has_fn!(self, hash)
847 }
848
849 #[inline]
851 pub fn has_default_in_place(&self) -> bool {
852 has_fn_sized!(self, default_in_place)
853 }
854
855 #[inline]
857 pub fn has_clone_into(&self) -> bool {
858 has_fn_sized!(self, clone_into)
859 }
860
861 #[inline]
863 pub fn has_parse(&self) -> bool {
864 has_fn_sized!(self, parse)
865 }
866 pub const fn builder<T>() -> ValueVTableBuilder<T> {
868 ValueVTableBuilder::new()
869 }
870
871 pub const fn builder_unsized<T: ?Sized>() -> ValueVTableBuilderUnsized<T> {
873 ValueVTableBuilderUnsized::new()
874 }
875}
876
877#[derive(Debug)]
879pub struct VTableView<T: ?Sized>(&'static ValueVTable, PhantomData<T>);
880
881impl<'a, T: crate::Facet<'a> + ?Sized> VTableView<&'a mut T> {
882 pub fn of_deref() -> Self {
884 Self(T::SHAPE.vtable, PhantomData)
885 }
886}
887
888impl<'a, T: crate::Facet<'a> + ?Sized> VTableView<&'a T> {
889 pub fn of_deref() -> Self {
891 Self(T::SHAPE.vtable, PhantomData)
892 }
893}
894
895macro_rules! get_fn {
896 ($self:expr, $name:tt) => {
897 match $self.0 {
898 ValueVTable::Sized(inner) => (inner.$name)().map(|f| unsafe { mem::transmute(f) }),
899 ValueVTable::Unsized(inner) => (inner.$name)().map(|f| unsafe { mem::transmute(f) }),
900 }
901 };
902}
903
904impl<'a, T: crate::Facet<'a> + ?Sized> VTableView<T> {
905 pub fn of() -> Self {
907 let this = Self(T::SHAPE.vtable, PhantomData);
908
909 match this.0 {
910 ValueVTable::Sized(_) => {
911 assert!(T::SHAPE.layout.sized_layout().is_ok());
912 assert_eq!(
913 core::mem::size_of::<*const T>(),
914 core::mem::size_of::<*const ()>()
915 );
916 }
917 ValueVTable::Unsized(_) => {
918 assert!(T::SHAPE.layout.sized_layout().is_err());
919 assert_eq!(
920 core::mem::size_of::<*const T>(),
921 2 * core::mem::size_of::<*const ()>()
922 );
923 }
924 }
925
926 this
927 }
928
929 #[inline(always)]
931 pub fn type_name(&self) -> TypeNameFn {
932 self.0.type_name()
933 }
934
935 #[inline(always)]
937 pub fn invariants(&self) -> Option<InvariantsFnTyped<T>> {
938 get_fn!(self, invariants)
939 }
940
941 #[inline(always)]
943 pub fn display(&self) -> Option<DisplayFnTyped<T>> {
944 get_fn!(self, display)
945 }
946
947 #[inline(always)]
949 pub fn debug(&self) -> Option<DebugFnTyped<T>> {
950 get_fn!(self, debug)
951 }
952
953 #[inline(always)]
955 pub fn partial_eq(&self) -> Option<PartialEqFnTyped<T>> {
956 get_fn!(self, partial_eq)
957 }
958
959 #[inline(always)]
961 pub fn partial_ord(&self) -> Option<PartialOrdFnTyped<T>> {
962 get_fn!(self, partial_ord)
963 }
964
965 #[inline(always)]
967 pub fn ord(&self) -> Option<CmpFnTyped<T>> {
968 get_fn!(self, ord)
969 }
970
971 #[inline(always)]
973 pub fn hash(&self) -> Option<HashFnTyped<T>> {
974 get_fn!(self, hash)
975 }
976
977 #[inline(always)]
981 pub fn try_borrow_inner(&self) -> Option<TryBorrowInnerFnTyped<T>> {
982 get_fn!(self, try_borrow_inner)
983 }
984}
985
986impl<'a, T: crate::Facet<'a>> VTableView<T> {
987 #[inline(always)]
989 pub fn default_in_place(&self) -> Option<DefaultInPlaceFnTyped<T>> {
990 (self.0.sized().unwrap().default_in_place)().map(|default_in_place| unsafe {
991 mem::transmute::<DefaultInPlaceFn, DefaultInPlaceFnTyped<T>>(default_in_place)
992 })
993 }
994
995 #[inline(always)]
997 pub fn clone_into(&self) -> Option<CloneIntoFnTyped<T>> {
998 (self.0.sized().unwrap().clone_into)().map(|clone_into| unsafe {
999 mem::transmute::<CloneIntoFn, CloneIntoFnTyped<T>>(clone_into)
1000 })
1001 }
1002
1003 #[inline(always)]
1005 pub fn parse(&self) -> Option<ParseFnTyped<T>> {
1006 (self.0.sized().unwrap().parse)()
1007 .map(|parse| unsafe { mem::transmute::<ParseFn, ParseFnTyped<T>>(parse) })
1008 }
1009
1010 #[inline(always)]
1022 pub fn try_from(&self) -> Option<TryFromFnTyped<T>> {
1023 (self.0.sized().unwrap().try_from)()
1024 .map(|try_from| unsafe { mem::transmute::<TryFromFn, TryFromFnTyped<T>>(try_from) })
1025 }
1026
1027 #[inline(always)]
1032 pub fn try_into_inner(&self) -> Option<TryIntoInnerFnTyped<T>> {
1033 (self.0.sized().unwrap().try_into_inner)().map(|try_into_inner| unsafe {
1034 mem::transmute::<TryIntoInnerFn, TryIntoInnerFnTyped<T>>(try_into_inner)
1035 })
1036 }
1037}
1038pub struct ValueVTableBuilder<T> {
1040 type_name: Option<TypeNameFn>,
1041 display: fn() -> Option<DisplayFn>,
1042 debug: fn() -> Option<DebugFn>,
1043 default_in_place: fn() -> Option<DefaultInPlaceFn>,
1044 clone_into: fn() -> Option<CloneIntoFn>,
1045 marker_traits: fn() -> MarkerTraits,
1046 partial_eq: fn() -> Option<PartialEqFn>,
1047 partial_ord: fn() -> Option<PartialOrdFn>,
1048 ord: fn() -> Option<CmpFn>,
1049 hash: fn() -> Option<HashFn>,
1050 drop_in_place: fn() -> Option<DropInPlaceFn>,
1051 invariants: fn() -> Option<InvariantsFn>,
1052 parse: fn() -> Option<ParseFn>,
1053 try_from: fn() -> Option<TryFromFn>,
1054 try_into_inner: fn() -> Option<TryIntoInnerFn>,
1055 try_borrow_inner: fn() -> Option<TryBorrowInnerFn>,
1056 _pd: PhantomData<T>,
1057}
1058
1059impl<T> ValueVTableBuilder<T> {
1060 #[allow(clippy::new_without_default)]
1062 pub const fn new() -> Self {
1063 Self {
1064 type_name: None,
1065 display: || None,
1066 debug: || None,
1067 default_in_place: || None,
1068 clone_into: || None,
1069 marker_traits: || MarkerTraits::empty(),
1070 partial_eq: || None,
1071 partial_ord: || None,
1072 ord: || None,
1073 hash: || None,
1074 drop_in_place: || {
1075 if mem::needs_drop::<T>() {
1076 Some(|value| unsafe { value.drop_in_place::<T>() })
1077 } else {
1078 None
1079 }
1080 },
1081 invariants: || None,
1082 parse: || None,
1083 try_from: || None,
1084 try_into_inner: || None,
1085 try_borrow_inner: || None,
1086 _pd: PhantomData,
1087 }
1088 }
1089
1090 pub const fn type_name(mut self, type_name: TypeNameFn) -> Self {
1092 self.type_name = Some(type_name);
1093 self
1094 }
1095
1096 pub const fn display(mut self, display: fn() -> Option<DisplayFnTyped<T>>) -> Self {
1098 self.display = unsafe {
1099 mem::transmute::<fn() -> Option<DisplayFnTyped<T>>, fn() -> Option<DisplayFn>>(display)
1100 };
1101 self
1102 }
1103
1104 pub const fn debug(mut self, debug: fn() -> Option<DebugFnTyped<T>>) -> Self {
1106 self.debug = unsafe {
1107 mem::transmute::<fn() -> Option<DebugFnTyped<T>>, fn() -> Option<DebugFn>>(debug)
1108 };
1109 self
1110 }
1111
1112 pub const fn default_in_place(
1114 mut self,
1115 default_in_place: fn() -> Option<DefaultInPlaceFnTyped<T>>,
1116 ) -> Self {
1117 self.default_in_place = unsafe {
1118 mem::transmute::<
1119 fn() -> Option<DefaultInPlaceFnTyped<T>>,
1120 fn() -> Option<DefaultInPlaceFn>,
1121 >(default_in_place)
1122 };
1123 self
1124 }
1125
1126 pub const fn clone_into(mut self, clone_into: fn() -> Option<CloneIntoFnTyped<T>>) -> Self {
1128 self.clone_into = unsafe {
1129 mem::transmute::<fn() -> Option<CloneIntoFnTyped<T>>, fn() -> Option<CloneIntoFn>>(
1130 clone_into,
1131 )
1132 };
1133 self
1134 }
1135
1136 pub const fn marker_traits(mut self, marker_traits: fn() -> MarkerTraits) -> Self {
1138 self.marker_traits = marker_traits;
1139 self
1140 }
1141
1142 pub const fn partial_eq(mut self, partial_eq: fn() -> Option<PartialEqFnTyped<T>>) -> Self {
1144 self.partial_eq = unsafe {
1145 mem::transmute::<fn() -> Option<PartialEqFnTyped<T>>, fn() -> Option<PartialEqFn>>(
1146 partial_eq,
1147 )
1148 };
1149 self
1150 }
1151
1152 pub const fn partial_ord(mut self, partial_ord: fn() -> Option<PartialOrdFnTyped<T>>) -> Self {
1154 self.partial_ord = unsafe {
1155 mem::transmute::<fn() -> Option<PartialOrdFnTyped<T>>, fn() -> Option<PartialOrdFn>>(
1156 partial_ord,
1157 )
1158 };
1159 self
1160 }
1161
1162 pub const fn ord(mut self, ord: fn() -> Option<CmpFnTyped<T>>) -> Self {
1164 self.ord =
1165 unsafe { mem::transmute::<fn() -> Option<CmpFnTyped<T>>, fn() -> Option<CmpFn>>(ord) };
1166 self
1167 }
1168
1169 pub const fn hash(mut self, hash: fn() -> Option<HashFnTyped<T>>) -> Self {
1171 self.hash = unsafe {
1172 mem::transmute::<fn() -> Option<HashFnTyped<T>>, fn() -> Option<HashFn>>(hash)
1173 };
1174 self
1175 }
1176
1177 pub const fn drop_in_place(mut self, drop_in_place: fn() -> Option<DropInPlaceFn>) -> Self {
1181 self.drop_in_place = drop_in_place;
1182 self
1183 }
1184
1185 pub const fn invariants(mut self, invariants: fn() -> Option<InvariantsFnTyped<T>>) -> Self {
1187 self.invariants = unsafe {
1188 mem::transmute::<fn() -> Option<InvariantsFnTyped<T>>, fn() -> Option<InvariantsFn>>(
1189 invariants,
1190 )
1191 };
1192 self
1193 }
1194
1195 pub const fn parse(mut self, parse: fn() -> Option<ParseFnTyped<T>>) -> Self {
1197 self.parse = unsafe {
1198 mem::transmute::<fn() -> Option<ParseFnTyped<T>>, fn() -> Option<ParseFn>>(parse)
1199 };
1200 self
1201 }
1202
1203 pub const fn try_from(mut self, try_from: fn() -> Option<TryFromFnTyped<T>>) -> Self {
1205 self.try_from = unsafe {
1206 mem::transmute::<fn() -> Option<TryFromFnTyped<T>>, fn() -> Option<TryFromFn>>(try_from)
1207 };
1208 self
1209 }
1210
1211 pub const fn try_into_inner(
1213 mut self,
1214 try_into_inner: fn() -> Option<TryIntoInnerFnTyped<T>>,
1215 ) -> Self {
1216 self.try_into_inner = unsafe {
1217 mem::transmute::<fn() -> Option<TryIntoInnerFnTyped<T>>, fn() -> Option<TryIntoInnerFn>>(
1218 try_into_inner,
1219 )
1220 };
1221 self
1222 }
1223
1224 pub const fn try_borrow_inner(
1226 mut self,
1227 try_borrow_inner: fn() -> Option<TryBorrowInnerFnTyped<T>>,
1228 ) -> Self {
1229 self.try_borrow_inner = unsafe {
1230 mem::transmute::<
1231 fn() -> Option<TryBorrowInnerFnTyped<T>>,
1232 fn() -> Option<TryBorrowInnerFn>,
1233 >(try_borrow_inner)
1234 };
1235 self
1236 }
1237
1238 pub const fn build(self) -> ValueVTable {
1240 ValueVTable::Sized(ValueVTableSized {
1241 type_name: self.type_name.unwrap(),
1242 marker_traits: self.marker_traits,
1243 invariants: self.invariants,
1244 display: self.display,
1245 debug: self.debug,
1246 default_in_place: self.default_in_place,
1247 clone_into: self.clone_into,
1248 partial_eq: self.partial_eq,
1249 partial_ord: self.partial_ord,
1250 ord: self.ord,
1251 hash: self.hash,
1252 parse: self.parse,
1253 try_from: self.try_from,
1254 try_into_inner: self.try_into_inner,
1255 try_borrow_inner: self.try_borrow_inner,
1256 drop_in_place: self.drop_in_place,
1257 })
1258 }
1259}
1260
1261pub struct ValueVTableBuilderUnsized<T: ?Sized> {
1263 type_name: Option<TypeNameFn>,
1264 display: fn() -> Option<DisplayFnWide>,
1265 debug: fn() -> Option<DebugFnWide>,
1266 marker_traits: fn() -> MarkerTraits,
1267 partial_eq: fn() -> Option<PartialEqFnWide>,
1268 partial_ord: fn() -> Option<PartialOrdFnWide>,
1269 ord: fn() -> Option<CmpFnWide>,
1270 hash: fn() -> Option<HashFnWide>,
1271 invariants: fn() -> Option<InvariantsFnWide>,
1272 try_borrow_inner: fn() -> Option<TryBorrowInnerFnWide>,
1273 _pd: PhantomData<T>,
1274}
1275
1276impl<T: ?Sized> ValueVTableBuilderUnsized<T> {
1277 #[allow(clippy::new_without_default)]
1279 pub const fn new() -> Self {
1280 Self {
1281 type_name: None,
1282 display: || None,
1283 debug: || None,
1284 marker_traits: || MarkerTraits::empty(),
1285 partial_eq: || None,
1286 partial_ord: || None,
1287 ord: || None,
1288 hash: || None,
1289 invariants: || None,
1290 try_borrow_inner: || None,
1291 _pd: PhantomData,
1292 }
1293 }
1294
1295 pub const fn type_name(mut self, type_name: TypeNameFn) -> Self {
1297 self.type_name = Some(type_name);
1298 self
1299 }
1300
1301 pub const fn display(mut self, display: fn() -> Option<DisplayFnTyped<T>>) -> Self {
1303 self.display = unsafe {
1304 mem::transmute::<fn() -> Option<DisplayFnTyped<T>>, fn() -> Option<DisplayFnWide>>(
1305 display,
1306 )
1307 };
1308 self
1309 }
1310
1311 pub const fn debug(mut self, debug: fn() -> Option<DebugFnTyped<T>>) -> Self {
1313 self.debug = unsafe {
1314 mem::transmute::<fn() -> Option<DebugFnTyped<T>>, fn() -> Option<DebugFnWide>>(debug)
1315 };
1316 self
1317 }
1318
1319 pub const fn marker_traits(mut self, marker_traits: fn() -> MarkerTraits) -> Self {
1321 self.marker_traits = marker_traits;
1322 self
1323 }
1324
1325 pub const fn partial_eq(mut self, partial_eq: fn() -> Option<PartialEqFnTyped<T>>) -> Self {
1327 self.partial_eq = unsafe {
1328 mem::transmute::<fn() -> Option<PartialEqFnTyped<T>>, fn() -> Option<PartialEqFnWide>>(
1329 partial_eq,
1330 )
1331 };
1332 self
1333 }
1334
1335 pub const fn partial_ord(mut self, partial_ord: fn() -> Option<PartialOrdFnTyped<T>>) -> Self {
1337 self.partial_ord = unsafe {
1338 mem::transmute::<fn() -> Option<PartialOrdFnTyped<T>>, fn() -> Option<PartialOrdFnWide>>(
1339 partial_ord,
1340 )
1341 };
1342 self
1343 }
1344
1345 pub const fn ord(mut self, ord: fn() -> Option<CmpFnTyped<T>>) -> Self {
1347 self.ord = unsafe {
1348 mem::transmute::<fn() -> Option<CmpFnTyped<T>>, fn() -> Option<CmpFnWide>>(ord)
1349 };
1350 self
1351 }
1352
1353 pub const fn hash(mut self, hash: fn() -> Option<HashFnTyped<T>>) -> Self {
1355 self.hash = unsafe {
1356 mem::transmute::<fn() -> Option<HashFnTyped<T>>, fn() -> Option<HashFnWide>>(hash)
1357 };
1358 self
1359 }
1360
1361 pub const fn invariants(mut self, invariants: fn() -> Option<InvariantsFnTyped<T>>) -> Self {
1363 self.invariants = unsafe {
1364 mem::transmute::<fn() -> Option<InvariantsFnTyped<T>>, fn() -> Option<InvariantsFnWide>>(
1365 invariants,
1366 )
1367 };
1368 self
1369 }
1370
1371 pub const fn try_borrow_inner(
1373 mut self,
1374 try_borrow_inner: fn() -> Option<TryBorrowInnerFnTyped<T>>,
1375 ) -> Self {
1376 self.try_borrow_inner = unsafe {
1377 mem::transmute::<
1378 fn() -> Option<TryBorrowInnerFnTyped<T>>,
1379 fn() -> Option<TryBorrowInnerFnWide>,
1380 >(try_borrow_inner)
1381 };
1382 self
1383 }
1384
1385 pub const fn build(self) -> ValueVTable {
1387 ValueVTable::Unsized(ValueVTableUnsized {
1388 type_name: self.type_name.unwrap(),
1389 marker_traits: self.marker_traits,
1390 invariants: self.invariants,
1391 display: self.display,
1392 debug: self.debug,
1393 partial_eq: self.partial_eq,
1394 partial_ord: self.partial_ord,
1395 ord: self.ord,
1396 hash: self.hash,
1397 try_borrow_inner: self.try_borrow_inner,
1398 drop_in_place: || None,
1400 })
1401 }
1402}