1use std::sync::Arc;
2use {crate::TextRange, crate::TextSize, std::convert::TryInto};
3
4use priv_in_pub::Sealed;
5mod priv_in_pub {
6 pub trait Sealed {}
7}
8
9pub trait TextLen: Copy + Sealed {
11 fn text_len(self) -> TextSize;
13}
14
15impl Sealed for &'_ str {}
16impl TextLen for &'_ str {
17 #[inline]
18 fn text_len(self) -> TextSize {
19 self.len().try_into().unwrap()
20 }
21}
22
23impl Sealed for &'_ String {}
24impl TextLen for &'_ String {
25 #[inline]
26 fn text_len(self) -> TextSize {
27 self.as_str().text_len()
28 }
29}
30
31impl Sealed for char {}
32impl TextLen for char {
33 #[inline]
34 #[expect(clippy::cast_possible_truncation)]
35 fn text_len(self) -> TextSize {
36 (self.len_utf8() as u32).into()
37 }
38}
39
40pub trait Ranged {
42 fn range(&self) -> TextRange;
44
45 fn start(&self) -> TextSize {
47 self.range().start()
48 }
49
50 fn end(&self) -> TextSize {
52 self.range().end()
53 }
54}
55
56impl Ranged for TextRange {
57 fn range(&self) -> TextRange {
58 *self
59 }
60}
61
62impl<T> Ranged for &T
63where
64 T: Ranged,
65{
66 fn range(&self) -> TextRange {
67 T::range(self)
68 }
69}
70
71impl<T> Ranged for Arc<T>
72where
73 T: Ranged,
74{
75 fn range(&self) -> TextRange {
76 T::range(self)
77 }
78}
79
80pub trait TextSlice: Sealed {
82 fn slice(&self, range: impl Ranged) -> &str;
91}
92
93impl Sealed for str {}
94
95impl TextSlice for str {
96 fn slice(&self, ranged: impl Ranged) -> &str {
97 &self[ranged.range()]
98 }
99}