Skip to content

Commit daa70c8

Browse files
committed
Don't blanket impl LenTextSize
1 parent aa8e477 commit daa70c8

File tree

2 files changed

+56
-28
lines changed

2 files changed

+56
-28
lines changed

src/traits.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use {
22
crate::TextSize,
3-
std::{convert::TryInto, ops::Deref},
3+
std::{borrow::Cow, convert::TryInto, rc::Rc, sync::Arc},
44
};
55

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

19-
impl<D> LenTextSize for &'_ D
20-
where
21-
D: Deref<Target = str>,
22-
{
19+
impl LenTextSize for char {
2320
#[inline]
2421
fn len_text_size(self) -> TextSize {
25-
self.deref().len_text_size()
22+
(self.len_utf8() as u32).into()
2623
}
2724
}
2825

29-
impl LenTextSize for char {
30-
#[inline]
26+
impl<D> LenTextSize for &'_ D
27+
where
28+
D: LenTextSize + Copy,
29+
{
3130
fn len_text_size(self) -> TextSize {
32-
(self.len_utf8() as u32).into()
31+
D::len_text_size(*self)
3332
}
3433
}
34+
35+
// Because we could not find a smart blanket impl to do this automatically and
36+
// cleanly (rust-analyzer/text-size#36), just provide a bunch of manual impls.
37+
// If a type fits in this macro and you need it to impl LenTextSize, just open
38+
// a PR and we are likely to accept it. Or use `TextSize::of::<&str>` for now.
39+
macro_rules! impl_lentextsize_for_string {
40+
($($ty:ty),+ $(,)?) => {$(
41+
impl LenTextSize for $ty {
42+
#[inline]
43+
fn len_text_size(self) -> TextSize {
44+
<&str>::len_text_size(self)
45+
}
46+
}
47+
)+};
48+
}
49+
50+
impl_lentextsize_for_string! {
51+
&Box<str>,
52+
&'_ String,
53+
&Cow<'_, str>,
54+
&Cow<'_, String>,
55+
&Arc<str>,
56+
&Arc<String>,
57+
&Rc<str>,
58+
&Rc<String>,
59+
}

tests/constructors.rs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
use {
2-
std::{borrow::Cow, ops::Deref},
2+
std::{borrow::Cow, sync::Arc},
33
text_size::*,
44
};
55

6-
struct StringLike<'a>(&'a str);
6+
#[derive(Copy, Clone)]
7+
struct BadRope<'a>(&'a [&'a str]);
78

8-
impl Deref for StringLike<'_> {
9-
type Target = str;
10-
fn deref(&self) -> &Self::Target {
11-
&self.0
9+
impl LenTextSize for BadRope<'_> {
10+
fn len_text_size(self) -> TextSize {
11+
self.0.iter().copied().map(LenTextSize::len_text_size).sum()
1212
}
1313
}
1414

1515
#[test]
1616
fn main() {
17-
let s = "";
18-
let _ = TextSize::of(&s);
19-
20-
let s = String::new();
21-
let _ = TextSize::of(&s);
22-
23-
let s = Cow::Borrowed("");
24-
let _ = TextSize::of(&s);
25-
26-
let s = Cow::Owned(String::new());
27-
let _ = TextSize::of(&s);
17+
macro_rules! test {
18+
($($expr:expr),+ $(,)?) => {
19+
$(let _ = TextSize::of($expr);)+
20+
};
21+
}
2822

29-
let s = StringLike("");
30-
let _ = TextSize::of(&s);
23+
test! {
24+
"",
25+
&"",
26+
'a',
27+
&'a',
28+
&String::new(),
29+
&String::new().into_boxed_str(),
30+
&Arc::new(String::new()),
31+
&Cow::Borrowed(""),
32+
BadRope(&[""]),
33+
}
3134
}

0 commit comments

Comments
 (0)