structural_typing/
access.rs

1//! Runtime field access for structural types.
2use core::marker::PhantomData;
3
4/// Uniform field access for Present, Optional, or Absent.
5pub trait Access<T> {
6    /// Compile-time constant indicating if this field is absent.
7    const IS_ABSENT: bool;
8
9    /// Get field reference if present.
10    fn get(&self) -> Option<&T>;
11    /// Get mutable field reference if present.
12    fn get_mut(&mut self) -> Option<&mut T>;
13}
14
15/// Helper function to check if a field is absent (used by serde).
16pub fn is_absent<A: Access<T>, T>(_value: &A) -> bool {
17    A::IS_ABSENT
18}
19
20impl<T> Access<T> for PhantomData<T> {
21    const IS_ABSENT: bool = true;
22
23    #[inline]
24    fn get(&self) -> Option<&T> {
25        None
26    }
27    #[inline]
28    fn get_mut(&mut self) -> Option<&mut T> {
29        None
30    }
31}
32
33impl<T: Sized> Access<T> for T {
34    const IS_ABSENT: bool = false;
35
36    #[inline]
37    fn get(&self) -> Option<&T> {
38        Some(self)
39    }
40    #[inline]
41    fn get_mut(&mut self) -> Option<&mut T> {
42        Some(self)
43    }
44}
45
46impl<T> Access<T> for Option<T> {
47    const IS_ABSENT: bool = false;
48
49    #[inline]
50    fn get(&self) -> Option<&T> {
51        self.as_ref()
52    }
53    #[inline]
54    fn get_mut(&mut self) -> Option<&mut T> {
55        self.as_mut()
56    }
57}