jiff/util/
borrow.rs

1/*!
2This module re-exports a "dumb" version of `std::borrow::Cow`.
3
4It doesn't have any of the generic goodness and doesn't support dynamically
5sized types. It's just either a `T` or a `&T`.
6
7We have pretty simplistic needs, and we use this simpler type that works
8in core-only mode.
9*/
10
11#[derive(Clone, Debug)]
12pub(crate) enum DumbCow<'a, T> {
13    Owned(T),
14    Borrowed(&'a T),
15}
16
17impl<'a, T> core::ops::Deref for DumbCow<'a, T> {
18    type Target = T;
19    fn deref(&self) -> &T {
20        match *self {
21            DumbCow::Owned(ref t) => t,
22            DumbCow::Borrowed(t) => t,
23        }
24    }
25}
26
27impl<'a, T: core::fmt::Display> core::fmt::Display for DumbCow<'a, T> {
28    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
29        core::fmt::Display::fmt(core::ops::Deref::deref(self), f)
30    }
31}
32
33/// A `Cow`, but can be used in core-only mode.
34///
35/// In core-only, the `Owned` variant doesn't exist.
36#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
37pub(crate) enum StringCow<'a> {
38    #[cfg(feature = "alloc")]
39    Owned(alloc::string::String),
40    Borrowed(&'a str),
41}
42
43impl<'a> StringCow<'a> {
44    /// Returns this `String` or `&str` as a `&str`.
45    ///
46    /// Like `std::borrow::Cow`, the lifetime of the string slice returned
47    /// is tied to `StringCow`, and _not_ the original lifetime of the string
48    /// slice.
49    pub(crate) fn as_str<'s>(&'s self) -> &'s str {
50        match *self {
51            #[cfg(feature = "alloc")]
52            StringCow::Owned(ref s) => s,
53            StringCow::Borrowed(s) => s,
54        }
55    }
56
57    /// Converts this cow into an "owned" variant, copying if necessary.
58    ///
59    /// If this cow is already an "owned" variant, then this is a no-op.
60    #[cfg(feature = "alloc")]
61    pub(crate) fn into_owned(self) -> StringCow<'static> {
62        use alloc::string::ToString;
63
64        match self {
65            StringCow::Owned(string) => StringCow::Owned(string),
66            StringCow::Borrowed(string) => {
67                StringCow::Owned(string.to_string())
68            }
69        }
70    }
71}
72
73impl<'a> core::ops::Deref for StringCow<'a> {
74    type Target = str;
75    fn deref(&self) -> &str {
76        self.as_str()
77    }
78}
79
80impl<'a> core::fmt::Display for StringCow<'a> {
81    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
82        core::fmt::Display::fmt(self.as_str(), f)
83    }
84}
85
86#[cfg(feature = "alloc")]
87impl From<alloc::string::String> for StringCow<'static> {
88    fn from(string: alloc::string::String) -> StringCow<'static> {
89        StringCow::Owned(string)
90    }
91}
92
93impl<'a> From<&'a str> for StringCow<'a> {
94    fn from(string: &'a str) -> StringCow<'a> {
95        StringCow::Borrowed(string)
96    }
97}