arch_pkg_db/misc/attachment/
utils.rs

1use super::{Attached, IntoAttached};
2use core::{mem::replace, ops::Deref};
3
4/// Return type of [`AttachedUtils::flatten`].
5type Flattened<Main, Attachment> =
6    Attached<<Main as AttachedUtils>::Main, (Attachment, <Main as AttachedUtils>::Attachment)>;
7
8/// Return type of [`AttachedUtils::transpose`].
9type Transposed<Main, Attachment> = Attached<
10    Attached<<Main as AttachedUtils>::Main, Attachment>,
11    <Main as AttachedUtils>::Attachment,
12>;
13
14/// Methods to interact with [`Attached`].
15pub trait AttachedUtils: Sized + sealed::Sealed {
16    /// Main data.
17    type Main;
18    /// Attached metadata.
19    type Attachment;
20
21    /// Get an immutable reference to the main data.
22    fn main(&self) -> &Self::Main;
23    /// Get a mutable reference to the main data.
24    fn main_mut(&mut self) -> &mut Self::Main;
25
26    /// Get an immutable reference to the attached metadata.
27    fn attachment(&self) -> &Self::Attachment;
28    /// Get a mutable reference to the attached data.
29    fn attachment_mut(&mut self) -> &mut Self::Attachment;
30
31    /// Separate the main data from the attached metadata.
32    fn into_tuple(self) -> (Self::Main, Self::Attachment);
33    /// Get two mutable reference to the main data and the attached metadata.
34    fn tuple_mut(&mut self) -> (&mut Self::Main, &mut Self::Attachment);
35
36    /// Discard the attached metadata.
37    fn into_main(self) -> Self::Main {
38        self.into_tuple().0
39    }
40
41    /// Get a copy of the attached metadata.
42    fn copy_attachment(&self) -> Self::Attachment
43    where
44        Self::Attachment: Copy,
45    {
46        *self.attachment()
47    }
48
49    /// Get a clone of the attached metadata.
50    fn clone_attachment(&self) -> Self::Attachment
51    where
52        Self::Attachment: Clone,
53    {
54        self.attachment().clone()
55    }
56
57    /// Map the main data.
58    fn map<F, Y>(self, f: F) -> Attached<Y, Self::Attachment>
59    where
60        F: FnOnce(Self::Main) -> Y,
61    {
62        let (main, attachment) = self.into_tuple();
63        f(main).into_attached(attachment)
64    }
65
66    /// Flatten a pair with nested main.
67    fn flatten(self) -> Flattened<Self::Main, Self::Attachment>
68    where
69        Self::Main: AttachedUtils,
70    {
71        let (main, attachment1) = self.into_tuple();
72        let (main, attachment2) = main.into_tuple();
73        main.into_attached((attachment1, attachment2))
74    }
75
76    /// Swap inner and outer attachment types of a pair with nested main.
77    fn transpose(self) -> Transposed<Self::Main, Self::Attachment>
78    where
79        Self::Main: AttachedUtils,
80    {
81        let (main, attachment1) = self.into_tuple();
82        let (main, attachment2) = main.into_tuple();
83        main.into_attached(attachment1).into_attached(attachment2)
84    }
85
86    /// Convert an immutable reference of a whole pair to an owned pair of immutable references.
87    fn as_deref(&self) -> Attached<&Self::Main, &Self::Attachment> {
88        self.main().into_attached(self.attachment())
89    }
90    /// Convert a mutable reference of a whole pair to an owned pair of mutable references.
91    fn as_deref_mut(&mut self) -> Attached<&mut Self::Main, &mut Self::Attachment> {
92        let (main, attachment) = self.tuple_mut();
93        main.into_attached(attachment)
94    }
95
96    /// [Copy] the bits of the main data.
97    fn copied(self) -> Attached<<Self::Main as Deref>::Target, Self::Attachment>
98    where
99        Self::Main: Deref<Target: Copy>,
100    {
101        self.map(|attached| *attached)
102    }
103
104    /// [Clone] the main data.
105    fn cloned(self) -> Attached<<Self::Main as Deref>::Target, Self::Attachment>
106    where
107        Self::Main: Deref<Target: Clone>,
108    {
109        self.map(|attached| attached.deref().clone())
110    }
111
112    /// [Copy] the bits of the attached metadata.
113    fn copied_attachment(self) -> Attached<Self::Main, <Self::Attachment as Deref>::Target>
114    where
115        Self::Attachment: Deref<Target: Copy>,
116    {
117        let (main, attachment) = self.into_tuple();
118        main.into_attached(*attachment)
119    }
120
121    /// [Clone] the attached metadata.
122    fn cloned_attachment(self) -> Attached<Self::Main, <Self::Attachment as Deref>::Target>
123    where
124        Self::Attachment: Deref<Target: Clone>,
125    {
126        let (main, attachment) = self.into_tuple();
127        main.into_attached(attachment.deref().clone())
128    }
129
130    /// Replace the main data.
131    fn replace(&mut self, main: Self::Main) -> Self::Main {
132        replace(self.main_mut(), main)
133    }
134
135    /// Replace the attached metadata.
136    fn replace_attachment(&mut self, attachment: Self::Attachment) -> Self::Attachment {
137        replace(self.attachment_mut(), attachment)
138    }
139}
140
141impl<Main, Attachment> sealed::Sealed for Attached<Main, Attachment> {}
142impl<Main, Attachment> AttachedUtils for Attached<Main, Attachment> {
143    type Main = Main;
144    type Attachment = Attachment;
145
146    fn main(&self) -> &Self::Main {
147        self
148    }
149
150    fn main_mut(&mut self) -> &mut Self::Main {
151        self
152    }
153
154    fn attachment(&self) -> &Self::Attachment {
155        &self.attachment
156    }
157
158    fn attachment_mut(&mut self) -> &mut Self::Attachment {
159        &mut self.attachment
160    }
161
162    fn into_tuple(self) -> (Self::Main, Self::Attachment) {
163        Attached::into_tuple(self)
164    }
165
166    fn tuple_mut(&mut self) -> (&mut Self::Main, &mut Self::Attachment) {
167        let Attached { main, attachment } = self;
168        (main, attachment)
169    }
170}
171
172mod sealed {
173    pub trait Sealed {}
174}