1#![warn(missing_docs)]
6#[cfg(feature = "serde")]
7extern crate serde;
8
9#[cfg(feature = "serde")]
10mod serde_impls;
11
12mod transitive_impl;
13
14use std::borrow::{Borrow, BorrowMut, Cow};
15use std::cmp::Ordering;
16use std::fmt;
17use std::hash::{Hash, Hasher};
18use std::ops::{Deref, DerefMut};
19use std::str::FromStr;
20
21#[derive(Debug)]
144pub enum MaybeOwned<'a, T: 'a> {
145 Owned(T),
147 Borrowed(&'a T),
149}
150
151#[derive(Debug)]
165pub enum MaybeOwnedMut<'a, T: 'a> {
166 Owned(T),
168 Borrowed(&'a mut T),
170}
171
172macro_rules! common_impls {
173 ($Name:ident) => {
174 impl<T> $Name<'_, T> {
175 pub fn is_owned(&self) -> bool {
177 match self {
178 Self::Owned(_) => true,
179 Self::Borrowed(_) => false,
180 }
181 }
182 }
183
184 impl<T: Clone> $Name<'_, T> {
185
186 pub fn into_owned(self) -> T {
190 match self {
191 Self::Owned(v) => v,
192 Self::Borrowed(v) => v.clone(),
193 }
194 }
195
196 pub fn make_owned(&mut self) -> &mut T {
226 match self {
227 Self::Owned(v) => v,
228 Self::Borrowed(v) => {
229 *self = Self::Owned(v.clone());
230 match self {
231 Self::Owned(v) => v,
232 Self::Borrowed(..) => unreachable!(),
233 }
234 }
235 }
236 }
237 }
238
239 impl<T> Deref for $Name<'_, T> {
240 type Target = T;
241
242 fn deref(&self) -> &T {
243 match self {
244 Self::Owned(v) => v,
245 Self::Borrowed(v) => v,
246 }
247 }
248 }
249
250 impl<T> AsRef<T> for $Name<'_, T> {
251 fn as_ref(&self) -> &T {
252 self
253 }
254 }
255
256 impl<T> From<T> for $Name<'_, T> {
257 fn from(v: T) -> Self {
258 Self::Owned(v)
259 }
260 }
261
262 impl<T> Borrow<T> for $Name<'_, T> {
263 fn borrow(&self) -> &T {
264 self
265 }
266 }
267
268 impl<T: Default> Default for $Name<'_, T> {
269 fn default() -> Self {
270 Self::Owned(T::default())
271 }
272 }
273
274 impl<'b, A: PartialEq<B>, B> PartialEq<$Name<'b, B>> for $Name<'_, A> {
275 #[inline]
276 fn eq(&self, other: &$Name<'b, B>) -> bool {
277 PartialEq::eq(self.deref(), other.deref())
278 }
279 }
280
281 impl<'a, T: Eq> Eq for $Name<'a, T> {}
282
283 impl<T: FromStr> FromStr for $Name<'_, T> {
284 type Err = T::Err;
285
286 fn from_str(s: &str) -> Result<Self, Self::Err> {
287 Ok(Self::Owned(T::from_str(s)?))
288 }
289 }
290
291 impl<T: PartialOrd> PartialOrd for $Name<'_, T> {
293 #[inline]
294 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
295 PartialOrd::partial_cmp(self.deref(), other.deref())
296 }
297 }
298
299 impl<T: Ord> Ord for $Name<'_, T> {
300 #[inline]
301 fn cmp(&self, other: &Self) -> Ordering {
302 Ord::cmp(self.deref(), other.deref())
303 }
304 }
305
306 impl<T: Hash> Hash for $Name<'_, T> {
307 #[inline]
308 fn hash<H: Hasher>(&self, state: &mut H) {
309 Hash::hash(self.deref(), state)
310 }
311 }
312
313 impl<'a, T: fmt::Display> fmt::Display for $Name<'a, T> {
314 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
315 match self {
316 Self::Owned(o) => fmt::Display::fmt(o, f),
317 Self::Borrowed(b) => fmt::Display::fmt(b, f),
318 }
319 }
320 }
321 };
322}
323
324common_impls!(MaybeOwned);
325common_impls!(MaybeOwnedMut);
326
327impl<'a, T> From<&'a T> for MaybeOwned<'a, T> {
328 fn from(v: &'a T) -> Self {
329 Self::Borrowed(v)
330 }
331}
332
333impl<'a, T> From<&'a mut T> for MaybeOwnedMut<'a, T> {
334 fn from(v: &'a mut T) -> Self {
335 Self::Borrowed(v)
336 }
337}
338
339impl<'a, T: ToOwned<Owned = T>> From<Cow<'a, T>> for MaybeOwned<'a, T> {
340 fn from(cow: Cow<'a, T>) -> MaybeOwned<'a, T> {
341 match cow {
342 Cow::Owned(v) => MaybeOwned::Owned(v),
343 Cow::Borrowed(v) => MaybeOwned::Borrowed(v),
344 }
345 }
346}
347
348impl<'a, T: ToOwned<Owned = T>> Into<Cow<'a, T>> for MaybeOwned<'a, T> {
349 fn into(self) -> Cow<'a, T> {
350 match self {
351 MaybeOwned::Owned(v) => Cow::Owned(v),
352 MaybeOwned::Borrowed(v) => Cow::Borrowed(v),
353 }
354 }
355}
356
357impl<T: Clone> Clone for MaybeOwned<'_, T> {
358 fn clone(&self) -> Self {
359 match self {
360 Self::Owned(v) => Self::Owned(v.clone()),
361 Self::Borrowed(v) => Self::Borrowed(v),
362 }
363 }
364}
365
366impl<T> MaybeOwned<'_, T> {
367 pub fn as_mut(&mut self) -> Option<&mut T> {
372 match self {
373 MaybeOwned::Owned(value) => Some(value),
374 MaybeOwned::Borrowed(_) => None
375 }
376 }
377}
378
379impl<T: Clone> MaybeOwned<'_, T> {
380 #[deprecated = "use `make_owned` instead"]
405 pub fn to_mut(&mut self) -> &mut T {
406 match *self {
407 Self::Owned(ref mut v) => v,
408 Self::Borrowed(v) => {
409 *self = Self::Owned(v.clone());
410 match *self {
411 Self::Owned(ref mut v) => v,
412 Self::Borrowed(..) => unreachable!(),
413 }
414 }
415 }
416 }
417}
418
419impl<T> DerefMut for MaybeOwnedMut<'_, T> {
420 fn deref_mut(&mut self) -> &mut T {
421 match self {
422 Self::Owned(v) => v,
423 Self::Borrowed(v) => v,
424 }
425 }
426}
427
428impl<T> AsMut<T> for MaybeOwnedMut<'_, T> {
429 fn as_mut(&mut self) -> &mut T {
430 match self {
431 Self::Owned(v) => v,
432 Self::Borrowed(v) => v,
433 }
434 }
435}
436
437impl<T> BorrowMut<T> for MaybeOwnedMut<'_, T> {
438 fn borrow_mut(&mut self) -> &mut T {
439 self
440 }
441}
442
443#[cfg(test)]
444mod tests {
445 use super::*;
446
447 type TestType = Vec<()>;
448
449 fn with_into<'a, I: Into<MaybeOwned<'a, TestType>>>(v: I) -> MaybeOwned<'a, TestType> {
450 v.into()
451 }
452
453 #[test]
454 fn is_owned() {
455 let data = TestType::default();
456 assert!(MaybeOwned::Owned(data).is_owned());
457 }
458
459 #[test]
460 fn make_owned() {
461 let mut a = MaybeOwned::Borrowed(&12u8);
462 assert!(!a.is_owned());
463 a.make_owned();
464 assert!(a.is_owned());
465 assert_eq!(&*a, &12);
466 }
467
468 #[test]
469 fn into_with_owned() {
470 let data = TestType::default();
472 assert!(with_into(data).is_owned())
473 }
474 #[test]
475 fn into_with_borrow() {
476 let data = TestType::default();
478 assert!(!with_into(&data).is_owned());
479 }
480
481 #[test]
482 fn clone_owned() {
483 let maybe = MaybeOwned::<TestType>::default();
484 assert!(maybe.clone().is_owned());
485 }
486
487 #[test]
488 fn clone_borrow() {
489 let data = TestType::default();
490 let maybe: MaybeOwned<TestType> = (&data).into();
491 assert!(!maybe.clone().is_owned());
492 }
493
494 #[test]
495 fn to_mut() {
496 let data = TestType::default();
497 let mut maybe: MaybeOwned<TestType> = (&data).into();
498 assert!(!maybe.is_owned());
499 {
500 #[allow(deprecated)]
501 let _mut_ref = maybe.to_mut();
502 }
503 assert!(maybe.is_owned());
504 }
505
506 #[test]
507 fn into_inner() {
508 let data = vec![1u32, 2];
509 let maybe: MaybeOwned<Vec<u32>> = (&data).into();
510 assert_eq!(data, maybe.into_owned());
511 }
512
513 #[test]
514 fn has_default() {
515 #[derive(Default)]
516 struct TestType(u8);
517 let _x: MaybeOwned<TestType> = Default::default();
518 }
519
520 #[test]
521 fn has_clone() {
522 #[derive(Clone)]
523 struct TestType(u8);
524 let _x = TestType(12).clone();
525 }
526
527 #[test]
528 fn has_deref() {
529 let a = MaybeOwned::Owned(vec![1u8]);
530 let _ = a.len();
531
532 let a = MaybeOwnedMut::Owned(vec![1u8]);
533 let _ = a.len();
534 }
535
536 #[test]
537 fn has_deref_mut() {
538 let mut a = MaybeOwnedMut::Owned(vec![1u8]);
539 a[0] = 12u8;
540 }
541
542 #[test]
543 fn has_partial_eq() {
544 #[derive(PartialEq)]
545 struct TestType(f32);
546
547 let n = TestType(33.0);
548 let a = MaybeOwned::Owned(TestType(42.0));
549 let b = MaybeOwned::Borrowed(&n);
550 let c = MaybeOwned::Owned(TestType(33.0));
551
552 assert_eq!(a == b, false);
553 assert_eq!(b == c, true);
554 assert_eq!(c == a, false);
555 }
556
557 #[test]
558 fn has_eq() {
559 #[derive(PartialEq, Eq)]
560 struct TestType(i32);
561
562 let n = TestType(33);
563 let a = MaybeOwned::Owned(TestType(42));
564 let b = MaybeOwned::Borrowed(&n);
565 let c = MaybeOwned::Owned(TestType(33));
566
567 assert_eq!(a == b, false);
568 assert_eq!(b == c, true);
569 assert_eq!(c == a, false);
570 }
571
572 #[test]
573 fn has_partial_ord() {
574 #[derive(PartialEq, PartialOrd)]
575 struct TestType(f32);
576
577 let n = TestType(33.0);
578 let a = MaybeOwned::Owned(TestType(42.0));
579 let b = MaybeOwned::Borrowed(&n);
580 let c = MaybeOwned::Owned(TestType(33.0));
581
582 assert_eq!(a > b, true);
583 assert_eq!(b > c, false);
584 assert_eq!(a < c, false);
585 }
586
587 #[test]
588 fn has_ord() {
589 #[derive(PartialEq, Eq, PartialOrd, Ord)]
590 struct TestType(i32);
591
592 let n = TestType(33);
593 let a = MaybeOwned::Owned(TestType(42));
594 let b = MaybeOwned::Borrowed(&n);
595 let c = MaybeOwned::Owned(TestType(33));
596
597 assert_eq!(a > b, true);
598 assert_eq!(b > c, false);
599 assert_eq!(a < c, false);
600 }
601
602 #[test]
603 fn has_hash() {
604 use std::collections::HashMap;
605
606 let mut map = HashMap::new();
607 map.insert(MaybeOwned::Owned(42), 33);
608
609 assert_eq!(map.get(&MaybeOwned::Borrowed(&42)), Some(&33));
610 }
611
612 #[test]
613 fn has_borrow() {
614 let v = MaybeOwned::Owned(42);
615 let _ = Borrow::<u8>::borrow(&v);
616
617 let v = MaybeOwnedMut::Owned(42);
618 let _ = Borrow::<u8>::borrow(&v);
619 }
620
621 #[test]
622 fn has_borrow_mut() {
623 let mut v = MaybeOwnedMut::Owned(42);
624 let _ = BorrowMut::<u8>::borrow_mut(&mut v);
625 }
626
627 #[test]
628 fn has_as_ref() {
629 let v = MaybeOwned::Owned(42);
630 let _ = AsRef::<u8>::borrow(&v);
631
632 let v = MaybeOwnedMut::Owned(42);
633 let _ = AsRef::<u8>::borrow(&v);
634 }
635
636 #[test]
637 fn has_as_mut() {
638 let mut v: MaybeOwned<u8> = (&11).into();
640 assert_eq!(v.as_mut(), None);
641
642 let mut v: MaybeOwned<u8> = 12.into();
643 assert_eq!(v.as_mut(), Some(&mut 12));
644
645 let mut v = MaybeOwnedMut::Owned(42);
647 let _ = AsMut::<u8>::borrow_mut(&mut v);
648 }
649
650 #[test]
651 fn has_display() {
652 let n = 33;
653 let a = MaybeOwned::Owned(42);
654 let b = MaybeOwned::Borrowed(&n);
655
656 let s = format!("{} {}", a, b);
657
658 assert_eq!(s, "42 33");
659 }
660
661 #[test]
662 fn from_cow() {
663 use std::borrow::Cow;
664
665 fn test<'a, V: Into<MaybeOwned<'a, i32>>>(v: V, n: i32) {
666 assert_eq!(*v.into(), n)
667 }
668
669 let n = 33;
670 test(Cow::Owned(42), 42);
671 test(Cow::Borrowed(&n), n);
672 }
673
674 #[test]
675 fn into_cow() {
676 use std::borrow::Cow;
677
678 fn test<'a, V: Into<Cow<'a, i32>>>(v: V, n: i32) {
679 assert_eq!(*v.into(), n)
680 }
681
682 let n = 33;
683 test(MaybeOwned::Owned(42), 42);
684 test(MaybeOwned::Borrowed(&n), n);
685 }
686
687 #[test]
688 fn from_str() {
689 let as_string = "12";
690 assert_eq!(12u32, as_string.parse().unwrap());
692 assert_eq!(MaybeOwned::Owned(12u32), as_string.parse().unwrap());
693 }
694
695 #[test]
696 fn as_ref() {
697 let data = TestType::default();
698 let maybe_owned = MaybeOwned::Borrowed(&data);
699 let _ref: &TestType = maybe_owned.as_ref();
700 assert_eq!(&data as *const _ as usize, _ref as *const _ as usize);
701 }
702
703 #[test]
704 fn borrow() {
705 use std::borrow::Borrow;
706
707 let data = TestType::default();
708 let maybe_owned = MaybeOwned::Borrowed(&data);
709 let _ref: &TestType = maybe_owned.borrow();
710 assert_eq!(&data as *const _ as usize, _ref as *const _ as usize);
711 }
712
713 #[test]
714 fn reborrow_mut() {
715 let value = vec![0u32];
716 let mut value = MaybeOwnedMut::Owned(value);
717 let mut reborrow = MaybeOwnedMut::Borrowed(value.deref_mut());
718 reborrow.push(1);
719 assert_eq!(&[0, 1], &value[..]);
720 }
721}