Unnamed repository; edit this file 'description' to name the repository.
Merge pull request rust-analyzer/text-size#37 from CAD97/more-lentextsize
Don't blanket impl LenTextSize
Aleksey Kladov 2020-03-31
parent 2a09282 · parent c9220dd · commit 4527c63
-rw-r--r--lib/text-size/src/traits.rs43
-rw-r--r--lib/text-size/tests/constructors.rs41
2 files changed, 56 insertions, 28 deletions
diff --git a/lib/text-size/src/traits.rs b/lib/text-size/src/traits.rs
index 65f6445a1e..3944030c62 100644
--- a/lib/text-size/src/traits.rs
+++ b/lib/text-size/src/traits.rs
@@ -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.
@@ -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>,
+}
diff --git a/lib/text-size/tests/constructors.rs b/lib/text-size/tests/constructors.rs
index eba587b539..1022a4168b 100644
--- a/lib/text-size/tests/constructors.rs
+++ b/lib/text-size/tests/constructors.rs
@@ -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(&[""]),
+ }
}