structural_typing/
access.rs

1//! Runtime field access for structural types.
2use core::marker::PhantomData;
3
4use crate::presence::InferPresence;
5
6/// Uniform field access for Present, Optional, or Absent.
7pub trait Access<T>: InferPresence<T> {
8    /// Compile-time constant indicating if this field is absent.
9    const IS_ABSENT: bool;
10
11    /// Remainder type when extracting Self from Source.
12    type RemainderFrom<Source: Access<T>>: Access<T>;
13
14    /// Get field reference if present.
15    fn get(&self) -> Option<&T>;
16    /// Get mutable field reference if present.
17    fn get_mut(&mut self) -> Option<&mut T>;
18    /// Consume and convert to Option.
19    fn into_option(self) -> Option<T>;
20}
21
22/// Helper function to check if a field is absent (used by serde).
23pub fn is_absent<A: Access<T>, T>(_value: &A) -> bool {
24    A::IS_ABSENT
25}
26
27impl<T> Access<T> for PhantomData<T> {
28    const IS_ABSENT: bool = true;
29
30    type RemainderFrom<Source: Access<T>> = Source;
31
32    #[inline]
33    fn get(&self) -> Option<&T> {
34        None
35    }
36    #[inline]
37    fn get_mut(&mut self) -> Option<&mut T> {
38        None
39    }
40    #[inline]
41    fn into_option(self) -> Option<T> {
42        None
43    }
44}
45
46impl<T: Sized> Access<T> for T {
47    const IS_ABSENT: bool = false;
48
49    type RemainderFrom<Source: Access<T>> = PhantomData<T>;
50
51    #[inline]
52    fn get(&self) -> Option<&T> {
53        Some(self)
54    }
55    #[inline]
56    fn get_mut(&mut self) -> Option<&mut T> {
57        Some(self)
58    }
59    #[inline]
60    fn into_option(self) -> Option<T> {
61        Some(self)
62    }
63}
64
65impl<T> Access<T> for Option<T> {
66    const IS_ABSENT: bool = false;
67
68    type RemainderFrom<Source: Access<T>> = PhantomData<T>;
69
70    #[inline]
71    fn get(&self) -> Option<&T> {
72        self.as_ref()
73    }
74    #[inline]
75    fn get_mut(&mut self) -> Option<&mut T> {
76        self.as_mut()
77    }
78    #[inline]
79    fn into_option(self) -> Option<T> {
80        self
81    }
82}