facet_core/types/
value.rs

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
12//======== Type Information ========
13
14/// A function that formats the name of a type.
15///
16/// This helps avoid allocations, and it takes options.
17pub type TypeNameFn = fn(f: &mut core::fmt::Formatter, opts: TypeNameOpts) -> core::fmt::Result;
18
19/// Options for formatting the name of a type
20#[derive(Clone, Copy)]
21pub struct TypeNameOpts {
22    /// as long as this is > 0, keep formatting the type parameters
23    /// when it reaches 0, format type parameters as `...`
24    /// if negative, all type parameters are formatted
25    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    /// Create a new `NameOpts` for which none of the type parameters are formatted
37    #[inline]
38    pub fn none() -> Self {
39        Self { recurse_ttl: 0 }
40    }
41
42    /// Create a new `NameOpts` for which only the direct children are formatted
43    #[inline]
44    pub fn one() -> Self {
45        Self { recurse_ttl: 1 }
46    }
47
48    /// Create a new `NameOpts` for which all type parameters are formatted
49    #[inline]
50    pub fn infinite() -> Self {
51        Self { recurse_ttl: -1 }
52    }
53
54    /// Decrease the `recurse_ttl` — if it's != 0, returns options to pass when
55    /// formatting children type parameters.
56    ///
57    /// If this returns `None` and you have type parameters, you should render a
58    /// `…` (unicode ellipsis) character instead of your list of types.
59    ///
60    /// See the implementation for `Vec` for examples.
61    #[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
75//======== Invariants ========
76
77/// Function to validate the invariants of a value. If it returns false, the value is considered invalid.
78///
79/// # Safety
80///
81/// The `value` parameter must point to aligned, initialized memory of the correct type.
82pub type InvariantsFn = for<'mem> unsafe fn(value: PtrConst<'mem>) -> bool;
83
84/// Function to validate the invariants of a value. If it returns false, the value is considered invalid (wide pointer version).
85///
86/// # Safety
87///
88/// The `value` parameter must point to aligned, initialized memory of the correct type.
89pub type InvariantsFnWide = for<'mem> unsafe fn(value: PtrConstWide<'mem>) -> bool;
90
91/// Function to validate the invariants of a value. If it returns false, the value is considered invalid.
92pub type InvariantsFnTyped<T> = fn(value: &T) -> bool;
93
94//======== Memory Management ========
95
96/// Function to drop a value
97///
98/// # Safety
99///
100/// The `value` parameter must point to aligned, initialized memory of the correct type.
101/// After calling this function, the memory pointed to by `value` should not be accessed again
102/// until it is properly reinitialized.
103pub type DropInPlaceFn = for<'mem> unsafe fn(value: PtrMut<'mem>) -> PtrUninit<'mem>;
104
105/// Function to drop a value (wide pointer version)
106///
107/// # Safety
108///
109/// The `value` parameter must point to aligned, initialized memory of the correct type.
110/// After calling this function, the memory pointed to by `value` should not be accessed again
111/// until it is properly reinitialized.
112pub type DropInPlaceFnWide = for<'mem> unsafe fn(value: PtrMutWide<'mem>) -> PtrUninitWide<'mem>;
113
114/// Function to clone a value into another already-allocated value
115///
116/// # Safety
117///
118/// The `source` parameter must point to aligned, initialized memory of the correct type.
119/// The `target` parameter has the correct layout and alignment, but points to
120/// uninitialized memory. The function returns the same pointer wrapped in an [`PtrMut`].
121pub type CloneIntoFn =
122    for<'src, 'dst> unsafe fn(source: PtrConst<'src>, target: PtrUninit<'dst>) -> PtrMut<'dst>;
123/// Function to clone a value into another already-allocated value
124pub type CloneIntoFnTyped<T> =
125    for<'src, 'dst> fn(source: &'src T, target: TypedPtrUninit<'dst, T>) -> &'dst mut T;
126
127/// Function to set a value to its default in-place
128///
129/// # Safety
130///
131/// The `target` parameter has the correct layout and alignment, but points to
132/// uninitialized memory. The function returns the same pointer wrapped in an [`PtrMut`].
133pub type DefaultInPlaceFn = for<'mem> unsafe fn(target: PtrUninit<'mem>) -> PtrMut<'mem>;
134/// Function to set a value to its default in-place
135pub type DefaultInPlaceFnTyped<T> = for<'mem> fn(target: TypedPtrUninit<'mem, T>) -> &'mem mut T;
136
137//======== Conversion ========
138
139/// Function to parse a value from a string.
140///
141/// If both [`DisplayFn`] and [`ParseFn`] are set, we should be able to round-trip the value.
142///
143/// # Safety
144///
145/// The `target` parameter has the correct layout and alignment, but points to
146/// uninitialized memory. If this function succeeds, it should return `Ok` with the
147/// same pointer wrapped in an [`PtrMut`]. If parsing fails, it returns `Err` with an error.
148pub type ParseFn =
149    for<'mem> unsafe fn(s: &str, target: PtrUninit<'mem>) -> Result<PtrMut<'mem>, ParseError>;
150
151/// Function to parse a value from a string.
152///
153/// If both [`DisplayFn`] and [`ParseFn`] are set, we should be able to round-trip the value.
154pub type ParseFnTyped<T> =
155    for<'mem> fn(s: &str, target: TypedPtrUninit<'mem, T>) -> Result<&'mem mut T, ParseError>;
156
157/// Error returned by [`ParseFn`]
158#[derive(Debug)]
159pub enum ParseError {
160    /// Generic error message
161    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
174/// Function to try converting from another type
175///
176/// # Safety
177///
178/// The `target` parameter has the correct layout and alignment, but points to
179/// uninitialized memory. If this function succeeds, it should return `Ok` with the
180/// same pointer wrapped in an [`PtrMut`]. If conversion fails, it returns `Err` with an error.
181pub 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
187/// Function to try converting from another type
188pub 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/// Error type for TryFrom conversion failures
195#[derive(Debug, PartialEq, Clone)]
196pub enum TryFromError {
197    /// Generic conversion error
198    Generic(&'static str),
199
200    /// The target shape doesn't implement conversion from any source shape (no try_from in vtable)
201    Unimplemented,
202
203    /// The target shape has a conversion implementation, but it doesn't support converting from this specific source shape
204    UnsupportedSourceShape {
205        /// The source shape that failed to convert
206        src_shape: &'static Shape,
207
208        /// The shapes that the `TryFrom` implementation supports
209        expected: &'static [&'static Shape],
210    },
211
212    /// `!Sized` type
213    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
252/// Function to convert a transparent/newtype wrapper into its inner type.
253///
254/// This is used for types that wrap another type (like smart pointers, newtypes, etc.)
255/// where the wrapper can be unwrapped to access the inner value. Primarily used during serialization.
256///
257/// # Safety
258///
259/// This function is unsafe because it operates on raw pointers.
260///
261/// The `src_ptr` must point to a valid, initialized instance of the wrapper type.
262/// The `dst` pointer must point to valid, uninitialized memory suitable for holding an instance
263/// of the inner type.
264///
265/// The function will return a pointer to the initialized inner value.
266pub type TryIntoInnerFn = for<'src, 'dst> unsafe fn(
267    src_ptr: PtrMut<'src>,
268    dst: PtrUninit<'dst>,
269) -> Result<PtrMut<'dst>, TryIntoInnerError>;
270/// Function to convert a transparent/newtype wrapper into its inner type.
271///
272/// This is used for types that wrap another type (like smart pointers, newtypes, etc.)
273/// where the wrapper can be unwrapped to access the inner value. Primarily used during serialization.
274pub 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/// Error type returned by [`TryIntoInnerFn`] when attempting to extract
280/// the inner value from a wrapper type.
281#[derive(Debug, Clone, PartialEq, Eq)]
282pub enum TryIntoInnerError {
283    /// Indicates that the inner value cannot be extracted at this time,
284    /// such as when a mutable borrow is already active.
285    Unavailable,
286    /// Indicates that another unspecified error occurred during extraction.
287    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
303/// Function to borrow the inner value from a transparent/newtype wrapper without copying.
304///
305/// This is used for types that wrap another type (like smart pointers, newtypes, etc.)
306/// to efficiently access the inner value without transferring ownership.
307///
308/// # Safety
309///
310/// This function is unsafe because it operates on raw pointers.
311///
312/// The `src_ptr` must point to a valid, initialized instance of the wrapper type.
313/// The returned pointer points to memory owned by the wrapper and remains valid
314/// as long as the wrapper is valid and not mutated.
315pub type TryBorrowInnerFn =
316    for<'src> unsafe fn(src_ptr: PtrConst<'src>) -> Result<PtrConst<'src>, TryBorrowInnerError>;
317
318/// Function to borrow the inner value from a transparent/newtype wrapper without copying (wide pointer version).
319pub type TryBorrowInnerFnWide =
320    for<'src> unsafe fn(
321        src_ptr: PtrConstWide<'src>,
322    ) -> Result<PtrConstWide<'src>, TryBorrowInnerError>;
323
324/// Function to borrow the inner value from a transparent/newtype wrapper without copying.
325///
326/// This is used for types that wrap another type (like smart pointers, newtypes, etc.)
327/// to efficiently access the inner value without transferring ownership.
328pub type TryBorrowInnerFnTyped<T> =
329    for<'src> fn(src_ptr: &'src T) -> Result<&'src T, TryBorrowInnerError>;
330
331/// Error type returned by [`TryBorrowInnerFn`] when attempting to borrow
332/// the inner value from a wrapper type.
333#[derive(Debug, Clone, PartialEq, Eq)]
334pub enum TryBorrowInnerError {
335    /// Indicates that the inner value cannot be borrowed at this time,
336    /// such as when a mutable borrow is already active.
337    Unavailable,
338    /// Indicates an other, unspecified error occurred during the borrow attempt.
339    /// The contained string provides a description of the error.
340    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
358//======== Comparison ========
359
360/// Function to check if two values are partially equal
361///
362/// # Safety
363///
364/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
365pub type PartialEqFn = for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> bool;
366/// Function to check if two values are partially equal (wide pointer version)
367///
368/// # Safety
369///
370/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
371pub type PartialEqFnWide =
372    for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> bool;
373/// Function to check if two values are partially equal
374pub type PartialEqFnTyped<T> = fn(left: &T, right: &T) -> bool;
375
376/// Function to compare two values and return their ordering if comparable
377///
378/// # Safety
379///
380/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
381pub type PartialOrdFn =
382    for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> Option<Ordering>;
383/// Function to compare two values and return their ordering if comparable (wide pointer version)
384///
385/// # Safety
386///
387/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
388pub type PartialOrdFnWide =
389    for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> Option<Ordering>;
390/// Function to compare two values and return their ordering if comparable
391pub type PartialOrdFnTyped<T> = fn(left: &T, right: &T) -> Option<Ordering>;
392
393/// Function to compare two values and return their ordering
394///
395/// # Safety
396///
397/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
398pub type CmpFn = for<'l, 'r> unsafe fn(left: PtrConst<'l>, right: PtrConst<'r>) -> Ordering;
399/// Function to compare two values and return their ordering (wide pointer version)
400///
401/// # Safety
402///
403/// Both `left` and `right` parameters must point to aligned, initialized memory of the correct type.
404pub type CmpFnWide =
405    for<'l, 'r> unsafe fn(left: PtrConstWide<'l>, right: PtrConstWide<'r>) -> Ordering;
406/// Function to compare two values and return their ordering
407pub type CmpFnTyped<T> = fn(left: &T, right: &T) -> Ordering;
408
409//======== Hashing ========
410
411/// Function to hash a value
412///
413/// # Safety
414///
415/// The `value` parameter must point to aligned, initialized memory of the correct type.
416/// The hasher pointer must be a valid pointer to a Hasher trait object.
417pub type HashFn = for<'mem> unsafe fn(
418    value: PtrConst<'mem>,
419    // TODO: Should this be wide? According to the documentation this is a trait object
420    hasher_this: PtrMut<'mem>,
421    hasher_write_fn: HasherWriteFn,
422);
423
424/// Function to hash a value
425///
426/// # Safety
427///
428/// The `value` parameter must point to aligned, initialized memory of the correct type.
429/// The hasher pointer must be a valid pointer to a Hasher trait object.
430pub type HashFnWide = for<'mem> unsafe fn(
431    value: PtrConstWide<'mem>,
432
433    // TODO: Should this be wide? According to the documentation this is a trait object
434    hasher_this: PtrMut<'mem>,
435    hasher_write_fn: HasherWriteFn,
436);
437
438/// Function to hash a value
439pub type HashFnTyped<T> =
440    for<'mem> fn(value: &'mem T, hasher_this: PtrMut<'mem>, hasher_write_fn: HasherWriteFn);
441
442/// Function to write bytes to a hasher
443///
444/// # Safety
445///
446/// The `hasher_self` parameter must be a valid pointer to a hasher
447pub type HasherWriteFn = for<'mem> unsafe fn(hasher_self: PtrMut<'mem>, bytes: &[u8]);
448/// Function to write bytes to a hasher
449pub type HasherWriteFnTyped<T> = for<'mem> fn(hasher_self: &'mem mut T, bytes: &[u8]);
450
451/// Provides an implementation of [`core::hash::Hasher`] for a given hasher pointer and write function
452///
453/// See [`HashFn`] for more details on the parameters.
454pub struct HasherProxy<'a> {
455    hasher_this: PtrMut<'a>,
456    hasher_write_fn: HasherWriteFn,
457}
458
459impl<'a> HasherProxy<'a> {
460    /// Create a new `HasherProxy` from a hasher pointer and a write function
461    ///
462    /// # Safety
463    ///
464    /// The `hasher_this` parameter must be a valid pointer to a Hasher trait object.
465    /// The `hasher_write_fn` parameter must be a valid function pointer.
466    #[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
485//======== Marker Traits ========
486
487bitflags! {
488    /// Bitflags for common marker traits that a type may implement
489    ///
490    /// Note: facet is not able to see negative impls, so it might mistakenly think a struct `S`
491    /// is `Send` because all its fields are, ignoring that there is an `impl !Send for S`.
492    ///
493    /// Similarly, it might think a struct `S` is `!Send` just because one of the fields is an
494    /// `UnsafeCell` (which is `!Send`), ignoring that there is an `unsafe impl Send for S`.
495    ///
496    /// The reason facet's determination of `Send` or `!Send` is based on fields is because structs
497    /// can be generic, in which case our specialization trick does not work.
498    #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
499    pub struct MarkerTraits: u8 {
500        /// Indicates that the type implements the [`Eq`] marker trait
501        const EQ = 1 << 0;
502        /// Indicates that the type implements the [`Send`] marker trait.
503        ///
504        /// Note: this is a best-effort guess, see the documentation about negative impls in [MarkerTraits].
505        const SEND = 1 << 1;
506        /// Indicates that the type implements the [`Sync`] marker trait
507        ///
508        /// Note: this is a best-effort guess, see the documentation about negative impls in [MarkerTraits].
509        const SYNC = 1 << 2;
510        /// Indicates that the type implements the [`Copy`] marker trait
511        const COPY = 1 << 3;
512        /// Indicates that the type implements the [`Unpin`] marker trait
513        const UNPIN = 1 << 4;
514        /// Indicates that the type implements the [`UnwindSafe`](core::panic::UnwindSafe) marker trait
515        ///
516        /// Note: this is a best-effort guess, see the documentation about negative impls in [MarkerTraits].
517        const UNWIND_SAFE = 1 << 5;
518        /// Indicates that the type implements the [`RefUnwindSafe`](core::panic::RefUnwindSafe) marker trait
519        ///
520        /// Note: this is a best-effort guess, see the documentation about negative impls in [MarkerTraits].
521        const REF_UNWIND_SAFE = 1 << 6;
522    }
523}
524
525//======== Display and Debug ========
526
527/// Function to format a value for display
528///
529/// If both [`DisplayFn`] and [`ParseFn`] are set, we should be able to round-trip the value.
530///
531/// # Safety
532///
533/// The `value` parameter must point to aligned, initialized memory of the correct type.
534pub type DisplayFn =
535    for<'mem> unsafe fn(value: PtrConst<'mem>, f: &mut core::fmt::Formatter) -> core::fmt::Result;
536
537/// Function to format a value for display (wide pointer version)
538///
539/// If both [`DisplayFnWide`] and [`ParseFn`] are set, we should be able to round-trip the value.
540///
541/// # Safety
542///
543/// The `value` parameter must point to aligned, initialized memory of the correct type.
544pub type DisplayFnWide = for<'mem> unsafe fn(
545    value: PtrConstWide<'mem>,
546    f: &mut core::fmt::Formatter,
547) -> core::fmt::Result;
548
549/// Function to format a value for display
550///
551/// If both [`DisplayFn`] and [`ParseFn`] are set, we should be able to round-trip the value.
552pub type DisplayFnTyped<T> = fn(value: &T, f: &mut core::fmt::Formatter) -> core::fmt::Result;
553
554/// Function to format a value for debug.
555/// If this returns None, the shape did not implement Debug.
556pub type DebugFn =
557    for<'mem> unsafe fn(value: PtrConst<'mem>, f: &mut core::fmt::Formatter) -> core::fmt::Result;
558
559/// Function to format a value for debug (wide pointer version).
560/// If this returns None, the shape did not implement Debug (wide).
561pub type DebugFnWide = for<'mem> unsafe fn(
562    value: PtrConstWide<'mem>,
563    f: &mut core::fmt::Formatter,
564) -> core::fmt::Result;
565
566/// Function to format a value for debug.
567/// If this returns None, the shape did not implement Debug.
568pub type DebugFnTyped<T> = fn(value: &T, f: &mut core::fmt::Formatter) -> core::fmt::Result;
569
570/// A vtable representing the operations that can be performed on a type,
571/// either for sized or unsized types.
572///
573/// This enum encapsulates the specific vtables for sized ([`ValueVTableSized`])
574/// and unsized ([`ValueVTableUnsized`]) shapes, allowing generic type-agnostic
575/// dynamic dispatch for core capabilities (clone, drop, compare, hash, etc).
576#[derive(Debug, Clone, Copy)]
577#[repr(C)]
578pub enum ValueVTable {
579    /// VTable for operations on sized types.
580    Sized(ValueVTableSized),
581    /// VTable for operations on unsized types.
582    Unsized(ValueVTableUnsized),
583}
584
585/// VTable for common operations that can be performed on any `Sized` shape
586#[derive(Debug, Clone, Copy)]
587#[repr(C)]
588pub struct ValueVTableSized {
589    /// cf. [`TypeNameFn`]
590    pub type_name: TypeNameFn,
591    /// Marker traits implemented by the type
592    // FIXME: move out of vtable, it's not really... functions.
593    // Belongs in Shape directly.
594    pub marker_traits: fn() -> MarkerTraits,
595
596    /// cf. [`DropInPlaceFn`] — if None, drops without side-effects
597    pub drop_in_place: fn() -> Option<DropInPlaceFn>,
598
599    /// cf. [`InvariantsFn`]
600    pub invariants: fn() -> Option<InvariantsFn>,
601
602    /// cf. [`DisplayFn`]
603    pub display: fn() -> Option<DisplayFn>,
604
605    /// cf. [`DebugFn`]
606    pub debug: fn() -> Option<DebugFn>,
607
608    /// cf. [`DefaultInPlaceFn`]
609    pub default_in_place: fn() -> Option<DefaultInPlaceFn>,
610
611    /// cf. [`CloneIntoFn`]
612    pub clone_into: fn() -> Option<CloneIntoFn>,
613
614    /// cf. [`PartialEqFn`] for equality comparison
615    pub partial_eq: fn() -> Option<PartialEqFn>,
616
617    /// cf. [`PartialOrdFn`] for partial ordering comparison
618    pub partial_ord: fn() -> Option<PartialOrdFn>,
619
620    /// cf. [`CmpFn`] for total ordering
621    pub ord: fn() -> Option<CmpFn>,
622
623    /// cf. [`HashFn`]
624    pub hash: fn() -> Option<HashFn>,
625
626    /// cf. [`ParseFn`]
627    pub parse: fn() -> Option<ParseFn>,
628
629    /// cf. [`TryFromFn`]
630    ///
631    /// This also acts as a "TryFromInner" — you can use it to go:
632    ///
633    ///   * `String` => `Utf8PathBuf`
634    ///   * `String` => `Uuid`
635    ///   * `T` => `Option<T>`
636    ///   * `T` => `Arc<T>`
637    ///   * `T` => `NonZero<T>`
638    ///   * etc.
639    ///
640    pub try_from: fn() -> Option<TryFromFn>,
641
642    /// cf. [`TryIntoInnerFn`]
643    ///
644    /// This is used by transparent types to convert the wrapper type into its inner value.
645    /// Primarily used during serialization.
646    pub try_into_inner: fn() -> Option<TryIntoInnerFn>,
647
648    /// cf. [`TryBorrowInnerFn`]
649    ///
650    /// This is used by transparent types to efficiently access the inner value without copying.
651    pub try_borrow_inner: fn() -> Option<TryBorrowInnerFn>,
652}
653
654/// VTable for common operations that can be performed on any `!Sized` shape
655#[derive(Debug, Clone, Copy)]
656#[repr(C)]
657pub struct ValueVTableUnsized {
658    /// cf. [`TypeNameFn`]
659    pub type_name: TypeNameFn,
660    /// Marker traits implemented by the type
661    // FIXME: move out of vtable, it's not really... functions.
662    // Belongs in Shape directly.
663    pub marker_traits: fn() -> MarkerTraits,
664
665    /// cf. [`DropInPlaceFnWide`] — if None, drops without side-effects
666    pub drop_in_place: fn() -> Option<DropInPlaceFnWide>,
667
668    /// cf. [`InvariantsFnWide`]
669    pub invariants: fn() -> Option<InvariantsFnWide>,
670
671    /// cf. [`DisplayFnWide`]
672    pub display: fn() -> Option<DisplayFnWide>,
673
674    /// cf. [`DebugFnWide`]
675    pub debug: fn() -> Option<DebugFnWide>,
676
677    /// cf. [`PartialEqFnWide`] for equality comparison
678    pub partial_eq: fn() -> Option<PartialEqFnWide>,
679
680    /// cf. [`PartialOrdFnWide`] for partial ordering comparison
681    pub partial_ord: fn() -> Option<PartialOrdFnWide>,
682
683    /// cf. [`CmpFnWide`] for total ordering
684    pub ord: fn() -> Option<CmpFnWide>,
685
686    /// cf. [`HashFnWide`]
687    pub hash: fn() -> Option<HashFnWide>,
688
689    /// cf. [`TryBorrowInnerFnWide`]
690    ///
691    /// This is used by transparent types to efficiently access the inner value without copying.
692    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    /// Returns a reference to the [`ValueVTableSized`] if this vtable is for a sized type.
715    ///
716    /// # Returns
717    ///
718    /// - `Some(&ValueVTableSized)` if the type is sized.
719    /// - `None` if the type is unsized.
720    pub const fn sized(&self) -> Option<&ValueVTableSized> {
721        match self {
722            ValueVTable::Sized(inner) => Some(inner),
723            ValueVTable::Unsized(_) => None,
724        }
725    }
726
727    /// Returns a mutable reference to the [`ValueVTableSized`] if this vtable is for a sized type.
728    ///
729    /// # Returns
730    ///
731    /// - `Some(&mut ValueVTableSized)` if the type is sized.
732    /// - `None` if the type is unsized.
733    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    /// Returns a reference to the [`ValueVTableUnsized`] if this vtable is for an unsized type.
741    ///
742    /// # Returns
743    ///
744    /// - `Some(&ValueVTableUnsized)` if the type is unsized.
745    /// - `None` if the type is sized.
746    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    /// Get the marker traits implemented for the type
754    #[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    /// Get the type name fn of the type
763    #[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    /// Check if the type implements the [`Eq`] marker trait
772    #[inline]
773    pub fn is_eq(&self) -> bool {
774        self.marker_traits().contains(MarkerTraits::EQ)
775    }
776
777    /// Check if the type implements the [`Send`] marker trait
778    #[inline]
779    pub fn is_send(&self) -> bool {
780        self.marker_traits().contains(MarkerTraits::SEND)
781    }
782
783    /// Check if the type implements the [`Sync`] marker trait
784    #[inline]
785    pub fn is_sync(&self) -> bool {
786        self.marker_traits().contains(MarkerTraits::SYNC)
787    }
788
789    /// Check if the type implements the [`Copy`] marker trait
790    #[inline]
791    pub fn is_copy(&self) -> bool {
792        self.marker_traits().contains(MarkerTraits::COPY)
793    }
794
795    /// Check if the type implements the [`Unpin`] marker trait
796    #[inline]
797    pub fn is_unpin(&self) -> bool {
798        self.marker_traits().contains(MarkerTraits::UNPIN)
799    }
800
801    /// Check if the type implements the [`UnwindSafe`](core::panic::UnwindSafe) marker trait
802    #[inline]
803    pub fn is_unwind_safe(&self) -> bool {
804        self.marker_traits().contains(MarkerTraits::UNWIND_SAFE)
805    }
806
807    /// Check if the type implements the [`RefUnwindSafe`](core::panic::RefUnwindSafe) marker trait
808    #[inline]
809    pub fn is_ref_unwind_safe(&self) -> bool {
810        self.marker_traits().contains(MarkerTraits::REF_UNWIND_SAFE)
811    }
812
813    /// Returns `true` if the type implements the [`Display`](core::fmt::Display) trait and the `display` function is available in the vtable.
814    #[inline]
815    pub fn has_display(&self) -> bool {
816        has_fn!(self, display)
817    }
818
819    /// Returns `true` if the type implements the [`Debug`] trait and the `debug` function is available in the vtable.
820    #[inline]
821    pub fn has_debug(&self) -> bool {
822        has_fn!(self, debug)
823    }
824
825    /// Returns `true` if the type implements the [`PartialEq`] trait and the `partial_eq` function is available in the vtable.
826    #[inline]
827    pub fn has_partial_eq(&self) -> bool {
828        has_fn!(self, partial_eq)
829    }
830
831    /// Returns `true` if the type implements the [`PartialOrd`] trait and the `partial_ord` function is available in the vtable.
832    #[inline]
833    pub fn has_partial_ord(&self) -> bool {
834        has_fn!(self, partial_ord)
835    }
836
837    /// Returns `true` if the type implements the [`Ord`] trait and the `ord` function is available in the vtable.
838    #[inline]
839    pub fn has_ord(&self) -> bool {
840        has_fn!(self, ord)
841    }
842
843    /// Returns `true` if the type implements the [`Hash`] trait and the `hash` function is available in the vtable.
844    #[inline]
845    pub fn has_hash(&self) -> bool {
846        has_fn!(self, hash)
847    }
848
849    /// Returns `true` if the type supports default-in-place construction via the vtable.
850    #[inline]
851    pub fn has_default_in_place(&self) -> bool {
852        has_fn_sized!(self, default_in_place)
853    }
854
855    /// Returns `true` if the type supports in-place cloning via the vtable.
856    #[inline]
857    pub fn has_clone_into(&self) -> bool {
858        has_fn_sized!(self, clone_into)
859    }
860
861    /// Returns `true` if the type supports parsing from a string via the vtable.
862    #[inline]
863    pub fn has_parse(&self) -> bool {
864        has_fn_sized!(self, parse)
865    }
866    /// Creates a new [`ValueVTableBuilder`]
867    pub const fn builder<T>() -> ValueVTableBuilder<T> {
868        ValueVTableBuilder::new()
869    }
870
871    /// Creates a new [`ValueVTableBuilderUnsized`]
872    pub const fn builder_unsized<T: ?Sized>() -> ValueVTableBuilderUnsized<T> {
873        ValueVTableBuilderUnsized::new()
874    }
875}
876
877/// A typed view of a [`ValueVTable`].
878#[derive(Debug)]
879pub struct VTableView<T: ?Sized>(&'static ValueVTable, PhantomData<T>);
880
881impl<'a, T: crate::Facet<'a> + ?Sized> VTableView<&'a mut T> {
882    /// Fetches the vtable for the type.
883    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    /// Fetches the vtable for the type.
890    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    /// Fetches the vtable for the type.
906    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    /// cf. [`TypeNameFn`]
930    #[inline(always)]
931    pub fn type_name(&self) -> TypeNameFn {
932        self.0.type_name()
933    }
934
935    /// cf. [`InvariantsFn`]
936    #[inline(always)]
937    pub fn invariants(&self) -> Option<InvariantsFnTyped<T>> {
938        get_fn!(self, invariants)
939    }
940
941    /// cf. [`DisplayFn`]
942    #[inline(always)]
943    pub fn display(&self) -> Option<DisplayFnTyped<T>> {
944        get_fn!(self, display)
945    }
946
947    /// cf. [`DebugFn`]
948    #[inline(always)]
949    pub fn debug(&self) -> Option<DebugFnTyped<T>> {
950        get_fn!(self, debug)
951    }
952
953    /// cf. [`PartialEqFn`] for equality comparison
954    #[inline(always)]
955    pub fn partial_eq(&self) -> Option<PartialEqFnTyped<T>> {
956        get_fn!(self, partial_eq)
957    }
958
959    /// cf. [`PartialOrdFn`] for partial ordering comparison
960    #[inline(always)]
961    pub fn partial_ord(&self) -> Option<PartialOrdFnTyped<T>> {
962        get_fn!(self, partial_ord)
963    }
964
965    /// cf. [`CmpFn`] for total ordering
966    #[inline(always)]
967    pub fn ord(&self) -> Option<CmpFnTyped<T>> {
968        get_fn!(self, ord)
969    }
970
971    /// cf. [`HashFn`]
972    #[inline(always)]
973    pub fn hash(&self) -> Option<HashFnTyped<T>> {
974        get_fn!(self, hash)
975    }
976
977    /// cf. [`TryBorrowInnerFn`]
978    ///
979    /// This is used by transparent types to efficiently access the inner value without copying.
980    #[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    /// cf. [`DefaultInPlaceFn`]
988    #[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    /// cf. [`CloneIntoFn`]
996    #[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    /// cf. [`ParseFn`]
1004    #[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    /// cf. [`TryFromFn`]
1011    ///
1012    /// This also acts as a "TryFromInner" — you can use it to go:
1013    ///
1014    ///   * `String` => `Utf8PathBuf`
1015    ///   * `String` => `Uuid`
1016    ///   * `T` => `Option<T>`
1017    ///   * `T` => `Arc<T>`
1018    ///   * `T` => `NonZero<T>`
1019    ///   * etc.
1020    ///
1021    #[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    /// cf. [`TryIntoInnerFn`]
1028    ///
1029    /// This is used by transparent types to convert the wrapper type into its inner value.
1030    /// Primarily used during serialization.
1031    #[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}
1038/// Builds a [`ValueVTable`]
1039pub 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    /// Creates a new [`ValueVTableBuilder`] with all fields set to `None`.
1061    #[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    /// Sets the type name function for this builder.
1091    pub const fn type_name(mut self, type_name: TypeNameFn) -> Self {
1092        self.type_name = Some(type_name);
1093        self
1094    }
1095
1096    /// Sets the display function for this builder.
1097    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    /// Sets the debug function for this builder.
1105    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    /// Sets the default_in_place function for this builder.
1113    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    /// Sets the clone_into function for this builder.
1127    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    /// Sets the marker traits for this builder.
1137    pub const fn marker_traits(mut self, marker_traits: fn() -> MarkerTraits) -> Self {
1138        self.marker_traits = marker_traits;
1139        self
1140    }
1141
1142    /// Sets the partial_eq function for this builder.
1143    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    /// Sets the partial_ord function for this builder.
1153    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    /// Sets the ord function for this builder.
1163    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    /// Sets the hash function for this builder.
1170    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    /// Overwrites the drop_in_place function for this builder.
1178    ///
1179    /// This is usually not necessary, the builder builder will default this to the appropriate type.
1180    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    /// Sets the invariants function for this builder.
1186    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    /// Sets the parse function for this builder.
1196    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    /// Sets the try_from function for this builder.
1204    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    /// Sets the try_into_inner function for this builder.
1212    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    /// Sets the borrow_inner function for this builder.
1225    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    /// Builds the [`ValueVTable`] from the current state of the builder.
1239    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
1261/// Builds a [`ValueVTable`] for a `!Sized` type
1262pub 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    /// Creates a new [`ValueVTableBuilder`] with all fields set to `None`.
1278    #[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    /// Sets the type name function for this builder.
1296    pub const fn type_name(mut self, type_name: TypeNameFn) -> Self {
1297        self.type_name = Some(type_name);
1298        self
1299    }
1300
1301    /// Sets the display function for this builder.
1302    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    /// Sets the debug function for this builder.
1312    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    /// Sets the marker traits for this builder.
1320    pub const fn marker_traits(mut self, marker_traits: fn() -> MarkerTraits) -> Self {
1321        self.marker_traits = marker_traits;
1322        self
1323    }
1324
1325    /// Sets the eq function for this builder.
1326    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    /// Sets the partial_ord function for this builder.
1336    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    /// Sets the ord function for this builder.
1346    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    /// Sets the hash function for this builder.
1354    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    /// Sets the invariants function for this builder.
1362    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    /// Sets the borrow_inner function for this builder.
1372    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    /// Builds the [`ValueVTable`] from the current state of the builder.
1386    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            // TODO: Add support for this
1399            drop_in_place: || None,
1400        })
1401    }
1402}