diff options
Diffstat (limited to 'src/util')
| -rw-r--r-- | src/util/eco_string.rs | 7 | ||||
| -rw-r--r-- | src/util/mod.rs | 20 |
2 files changed, 23 insertions, 4 deletions
diff --git a/src/util/eco_string.rs b/src/util/eco_string.rs index f1dfdfaf..ab8d5642 100644 --- a/src/util/eco_string.rs +++ b/src/util/eco_string.rs @@ -5,6 +5,8 @@ use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::rc::Rc; +use super::RcExt; + /// An economical string with inline storage and clone-on-write semantics. #[derive(Clone)] pub struct EcoString(Repr); @@ -293,10 +295,7 @@ impl From<EcoString> for String { fn from(s: EcoString) -> Self { match s.0 { Repr::Small { .. } => s.as_str().to_owned(), - Repr::Large(rc) => match Rc::try_unwrap(rc) { - Ok(string) => string, - Err(rc) => (*rc).clone(), - }, + Repr::Large(rc) => Rc::take(rc), } } } diff --git a/src/util/mod.rs b/src/util/mod.rs index 05dc9025..c4272c55 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -10,6 +10,7 @@ use std::cell::RefMut; use std::cmp::Ordering; use std::ops::Range; use std::path::{Component, Path, PathBuf}; +use std::rc::Rc; /// Additional methods for booleans. pub trait BoolExt { @@ -67,6 +68,25 @@ impl<T> OptionExt<T> for Option<T> { } } +/// Additional methods for reference-counted pointers. +pub trait RcExt<T> { + /// Takes the inner value if there is exactly one strong reference and + /// clones it otherwise. + fn take(self) -> T; +} + +impl<T> RcExt<T> for Rc<T> +where + T: Clone, +{ + fn take(self) -> T { + match Rc::try_unwrap(self) { + Ok(v) => v, + Err(rc) => (*rc).clone(), + } + } +} + /// Additional methods for slices. pub trait SliceExt<T> { /// Split a slice into consecutive groups with the same key. |
