raw_string/str/
index.rs

1use std::slice::SliceIndex;
2
3use super::RawStr;
4
5/// The equivalent of `SliceIndex` for `RawStr`.
6///
7/// # Usage
8///
9/// Normally, this trait is not used directly.
10/// Its functionality is exposed through `Index` and the `get` methods of `RawStr`.
11///
12/// # Implementors
13///
14/// `RawStrIndex` is automatically implemented for all that implement `SliceIndex<[u8]>`:
15///
16///   - a `SliceIndex<[u8], Output=[u8]>` automatically implements `RawStrIndex<Output=RawStr>`, and
17///   - a `SliceIndex<[u8], Output=u8>` automatically implements `RawStrIndex<Output=u8>`.
18///
19/// # Examples
20///
21/// ```
22/// # use raw_string::RawStr;
23/// let s = RawStr::from_str("hello world");
24/// let hello: &RawStr = &s[..5]; // This is a slice.
25/// let space: u8 = s[5]; // This is a single byte
26/// assert_eq!(hello, "hello");
27/// assert_eq!(space, b' ');
28/// ```
29pub trait RawStrIndex {
30	/// `RawStr` (for ranges) or `u8` (for single indexes).
31	type Output: ?Sized;
32	/// Get the range or byte from the given `&RawStr`.
33	fn get(self, s: &RawStr) -> Option<&Self::Output>;
34	/// Get the (mutable) range or byte from the given `&mut RawStr`.
35	fn get_mut(self, s: &mut RawStr) -> Option<&mut Self::Output>;
36	/// Like `get`, but unsafe and unchecked.
37	unsafe fn get_unchecked(self, s: &RawStr) -> &Self::Output;
38	/// Like `get_mut`, but unsafe and unchecked.
39	unsafe fn get_unchecked_mut(self, s: &mut RawStr) -> &mut Self::Output;
40	/// Like `get`, but panics on failure.
41	fn index(self, s: &RawStr) -> &Self::Output;
42	/// Like `get_mut`, but panics on failure.
43	fn index_mut(self, s: &mut RawStr) -> &mut Self::Output;
44}
45
46#[doc(hidden)]
47pub trait RawStrIndexOutput {
48	type Output: ?Sized;
49	fn into(&self) -> &Self::Output;
50	fn into_mut(&mut self) -> &mut Self::Output;
51}
52
53impl RawStrIndexOutput for [u8] {
54	type Output = RawStr;
55	#[inline]
56	fn into(&self) -> &RawStr {
57		RawStr::from_bytes(self)
58	}
59	#[inline]
60	fn into_mut(&mut self) -> &mut RawStr {
61		RawStr::from_bytes_mut(self)
62	}
63}
64
65impl RawStrIndexOutput for u8 {
66	type Output = u8;
67	#[inline]
68	fn into(&self) -> &u8 {
69		self
70	}
71	#[inline]
72	fn into_mut(&mut self) -> &mut u8 {
73		self
74	}
75}
76
77impl<I> RawStrIndex for I
78where
79	I: SliceIndex<[u8]>,
80	I::Output: RawStrIndexOutput + 'static,
81{
82	type Output = <<I as SliceIndex<[u8]>>::Output as RawStrIndexOutput>::Output;
83	#[inline]
84	fn get(self, s: &RawStr) -> Option<&Self::Output> {
85		s.as_bytes().get(self).map(RawStrIndexOutput::into)
86	}
87	#[inline]
88	fn get_mut(self, s: &mut RawStr) -> Option<&mut Self::Output> {
89		s.as_bytes_mut()
90			.get_mut(self)
91			.map(RawStrIndexOutput::into_mut)
92	}
93	#[inline]
94	unsafe fn get_unchecked(self, s: &RawStr) -> &Self::Output {
95		RawStrIndexOutput::into(s.as_bytes().get_unchecked(self))
96	}
97	#[inline]
98	unsafe fn get_unchecked_mut(self, s: &mut RawStr) -> &mut Self::Output {
99		RawStrIndexOutput::into_mut(s.as_bytes_mut().get_unchecked_mut(self))
100	}
101	#[inline]
102	fn index(self, s: &RawStr) -> &Self::Output {
103		RawStrIndexOutput::into(&s.as_bytes()[self])
104	}
105	#[inline]
106	fn index_mut(self, s: &mut RawStr) -> &mut Self::Output {
107		RawStrIndexOutput::into_mut(&mut s.as_bytes_mut()[self])
108	}
109}