From 5becb32ba463d6b0ace914ab06bb237483a94fbc Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 17 Oct 2021 14:38:48 +0200 Subject: Introduce page / block / inline levels --- src/util/eco_string.rs | 7 +++---- src/util/mod.rs | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'src/util') 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 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 OptionExt for Option { } } +/// Additional methods for reference-counted pointers. +pub trait RcExt { + /// Takes the inner value if there is exactly one strong reference and + /// clones it otherwise. + fn take(self) -> T; +} + +impl RcExt for Rc +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 { /// Split a slice into consecutive groups with the same key. -- cgit v1.2.3