Skip to content

Commit cf9e29e

Browse files
bors[bot]CAD97
andauthored
Merge #23
23: Add a deref-removing impl for TextSized r=CAD97 a=CAD97 Notably, given `s: &SmolStr`, `TextSize::of(s)` does not work, where `TextUnit::of_str(s)` did, because the concrete type could be deref-coerced to. (It's probably a limitation of the language that deref coersion does not apply here, but it's one we have to live with.) So we provide a blanket impl for any type that derefs (directly) to `str`. Alternatively, we can provide a deeper blanket impl that derefs any number of references recursively [[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=008b5e0c2edd332b34b3efa42ce2a40a)]: ```rust impl<D> TextSized for &'_ D where D: Deref, for<'a> &'a D::Target: TextSized, { #[inline] fn text_size(self) -> TextSize { self.deref().text_size() } } ``` This is "only" at the cost of a little extra impl complexity. Co-authored-by: CAD97 <[email protected]>
2 parents 246660c + 8a6f5e3 commit cf9e29e

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/traits.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use {crate::TextSize, std::convert::TryInto};
1+
use {
2+
crate::TextSize,
3+
std::{convert::TryInto, ops::Deref},
4+
};
25

36
/// Text-like structures that have a text size.
47
pub trait TextSized: Copy {
@@ -15,6 +18,16 @@ impl TextSized for &'_ str {
1518
}
1619
}
1720

21+
impl<D> TextSized for &'_ D
22+
where
23+
D: Deref<Target = str>,
24+
{
25+
#[inline]
26+
fn text_size(self) -> TextSize {
27+
self.deref().text_size()
28+
}
29+
}
30+
1831
impl TextSized for char {
1932
#[inline]
2033
fn text_size(self) -> TextSize {

tests/constructors.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use {
2+
std::{borrow::Cow, ops::Deref},
3+
text_size::*,
4+
};
5+
6+
struct StringLike<'a>(&'a str);
7+
8+
impl Deref for StringLike<'_> {
9+
type Target = str;
10+
fn deref(&self) -> &Self::Target {
11+
&self.0
12+
}
13+
}
14+
15+
#[test]
16+
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);
28+
29+
let s = StringLike("");
30+
let _ = TextSize::of(&s);
31+
}

0 commit comments

Comments
 (0)