Skip to content

Commit

Permalink
Merge pull request #37 from CAD97/more-lentextsize
Browse files Browse the repository at this point in the history
Don't blanket impl LenTextSize
  • Loading branch information
matklad authored Mar 31, 2020
2 parents 192b316 + 8061a90 commit 9161432
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 28 deletions.
43 changes: 34 additions & 9 deletions src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
crate::TextSize,
std::{convert::TryInto, ops::Deref},
std::{borrow::Cow, convert::TryInto, rc::Rc, sync::Arc},
};

/// Text-like structures that have a text size.
Expand All @@ -16,19 +16,44 @@ impl LenTextSize for &'_ str {
}
}

impl<D> LenTextSize for &'_ D
where
D: Deref<Target = str>,
{
impl LenTextSize for char {
#[inline]
fn len_text_size(self) -> TextSize {
self.deref().len_text_size()
(self.len_utf8() as u32).into()
}
}

impl LenTextSize for char {
#[inline]
impl<D> LenTextSize for &'_ D
where
D: LenTextSize + Copy,
{
fn len_text_size(self) -> TextSize {
(self.len_utf8() as u32).into()
D::len_text_size(*self)
}
}

// Because we could not find a smart blanket impl to do this automatically and
// cleanly (rust-analyzer/text-size#36), just provide a bunch of manual impls.
// If a type fits in this macro and you need it to impl LenTextSize, just open
// a PR and we are likely to accept it. Or use `TextSize::of::<&str>` for now.
macro_rules! impl_lentextsize_for_string {
($($ty:ty),+ $(,)?) => {$(
impl LenTextSize for $ty {
#[inline]
fn len_text_size(self) -> TextSize {
<&str>::len_text_size(self)
}
}
)+};
}

impl_lentextsize_for_string! {
&Box<str>,
&'_ String,
&Cow<'_, str>,
&Cow<'_, String>,
&Arc<str>,
&Arc<String>,
&Rc<str>,
&Rc<String>,
}
41 changes: 22 additions & 19 deletions tests/constructors.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
use {
std::{borrow::Cow, ops::Deref},
std::{borrow::Cow, sync::Arc},
text_size::*,
};

struct StringLike<'a>(&'a str);
#[derive(Copy, Clone)]
struct BadRope<'a>(&'a [&'a str]);

impl Deref for StringLike<'_> {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
impl LenTextSize for BadRope<'_> {
fn len_text_size(self) -> TextSize {
self.0.iter().map(TextSize::of).sum()
}
}

#[test]
fn main() {
let s = "";
let _ = TextSize::of(&s);

let s = String::new();
let _ = TextSize::of(&s);

let s = Cow::Borrowed("");
let _ = TextSize::of(&s);

let s = Cow::Owned(String::new());
let _ = TextSize::of(&s);
macro_rules! test {
($($expr:expr),+ $(,)?) => {
$(let _ = TextSize::of($expr);)+
};
}

let s = StringLike("");
let _ = TextSize::of(&s);
test! {
"",
&"",
'a',
&'a',
&String::new(),
&String::new().into_boxed_str(),
&Arc::new(String::new()),
&Cow::Borrowed(""),
BadRope(&[""]),
}
}

0 comments on commit 9161432

Please sign in to comment.