1#![deny(anonymous_parameters)]
8#![deny(elided_lifetimes_in_paths)]
9#![deny(ellipsis_inclusive_range_patterns)]
10#![deny(nonstandard_style)]
11#![deny(rust_2018_idioms)]
12#![deny(trivial_numeric_casts)]
13#![warn(unsafe_code)]
14#![deny(rustdoc::broken_intra_doc_links)]
15#![deny(unused)]
16#![warn(missing_copy_implementations)]
19#![warn(missing_debug_implementations)]
20#![warn(variant_size_differences)]
21#![warn(clippy::pedantic)]
24
25#[macro_use]
26mod util;
27pub mod read_only;
28
29use std::borrow::{Borrow, BorrowMut};
30use std::cmp::Ordering;
31use std::fmt::Display;
32use std::ops::{Deref, DerefMut};
33
34#[derive(Eq, Ord, Debug, Hash)]
36pub enum Borrowned<'b, T> {
37 Owned(T),
39 Borrowed(&'b mut T),
41}
42
43impl<'b, T> Borrowned<'b, T> {
44 pub fn is_owned(&self) -> bool {
57 matches!(*self, Self::Owned(_))
58 }
59 pub fn is_borrowed(&self) -> bool {
72 matches!(*self, Self::Borrowed(_))
73 }
74
75 pub fn into_owned(self) -> Result<T, Self> {
80 match self {
81 Borrowned::Owned(owned) => Ok(owned),
82 Borrowned::Borrowed(_) => Err(self),
83 }
84 }
85
86 pub fn into_borrowed(self) -> Result<&'b mut T, Self> {
91 match self {
92 Borrowned::Borrowed(borrowed) => Ok(borrowed),
93 Borrowned::Owned(_) => Err(self),
94 }
95 }
96
97 fn inner_ref(&self) -> &T {
98 match self {
99 Borrowned::Owned(owned) => owned,
100 Borrowned::Borrowed(borrowed) => *borrowed,
101 }
102 }
103
104 fn inner_mut(&mut self) -> &mut T {
105 match self {
106 Borrowned::Owned(owned) => owned,
107 Borrowned::Borrowed(borrowed) => *borrowed,
108 }
109 }
110}
111
112shared_impls!();
113
114impl<'b, T> DerefMut for Borrowned<'b, T> {
115 fn deref_mut(&mut self) -> &mut Self::Target {
116 self.inner_mut()
117 }
118}
119
120impl<'b, T> BorrowMut<T> for Borrowned<'b, T> {
121 fn borrow_mut(&mut self) -> &mut T {
122 self.inner_mut()
123 }
124}
125
126impl<'b, T> AsMut<T> for Borrowned<'b, T> {
127 fn as_mut(&mut self) -> &mut T {
128 self.inner_mut()
129 }
130}
131
132impl<'i, 'b, T> IntoIterator for &'i mut Borrowned<'b, T>
133where
134 &'i mut T: IntoIterator,
135{
136 type Item = <&'i mut T as IntoIterator>::Item;
137
138 type IntoIter = <&'i mut T as IntoIterator>::IntoIter;
139
140 fn into_iter(self) -> Self::IntoIter {
141 self.inner_mut().into_iter()
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use crate::Borrowned;
148
149 #[test]
150 fn into_owned_gives_owned_when_owned() {
151 let hw = "Hello World".to_string();
152 let ob = Borrowned::Owned(hw.clone());
153 let hw2 = ob.into_owned();
154
155 assert_eq!(hw2, Ok(hw));
156 }
157
158 #[test]
159 fn into_owned_gives_self_when_not_owned() {
160 let mut hw = "Hello World".to_string();
161 let ob = Borrowned::Borrowed(&mut hw);
162 let hw2 = ob.into_owned();
163
164 assert!(hw2.is_err());
165 }
166
167 #[test]
168 fn into_borrowed_gives_borrowed_when_borrowed() {
169 let mut hw = "Hello World".to_string();
170 let ob = Borrowned::Borrowed(&mut hw);
171 let hw2 = ob.into_borrowed();
172
173 assert!(hw2.is_ok());
174 }
175
176 #[test]
177 fn into_borrowed_gives_self_when_not_borrowed() {
178 let hw = "Hello World".to_string();
179 let ob = Borrowned::Owned(hw);
180 let hw2 = ob.into_borrowed();
181
182 assert!(hw2.is_err());
183 }
184}