trim_in_place/
lib.rs

1/*!
2# Trim in-place
3
4This crate is used for extending `String` in order to do in-place trimming.
5
6## Usage
7
8```rust
9use trim_in_place::TrimInPlace;
10
11let mut s = String::from(" 1234 abcd  ");
12
13s.trim_in_place();
14
15assert_eq!("1234 abcd", s);
16```
17
18## Benchmark
19
20```bash
21cargo bench
22```
23*/
24
25#![no_std]
26
27extern crate alloc;
28
29use core::intrinsics::copy;
30
31use alloc::string::String;
32
33pub trait TrimInPlace {
34    fn trim_in_place(&mut self) -> &str;
35    fn trim_start_in_place(&mut self) -> &str;
36    fn trim_end_in_place(&mut self) -> &str;
37
38    // TODO trim_matches with Pattern
39    fn trim_matches_in_place(&mut self, pat: char) -> &str;
40    fn trim_start_matches_in_place(&mut self, pat: char) -> &str;
41    fn trim_end_matches_in_place(&mut self, pat: char) -> &str;
42}
43
44impl TrimInPlace for String {
45    #[inline]
46    fn trim_in_place(&mut self) -> &str {
47        let trimmed_str = self.trim();
48
49        let trimmed_str_start_pointer = trimmed_str.as_ptr();
50        let trimmed_str_length = trimmed_str.len();
51
52        unsafe {
53            let v = self.as_mut_vec();
54
55            copy(trimmed_str_start_pointer, v.as_mut_ptr(), trimmed_str_length);
56
57            v.set_len(trimmed_str_length);
58        }
59
60        self.as_str()
61    }
62
63    #[inline]
64    fn trim_start_in_place(&mut self) -> &str {
65        let trimmed_str = self.trim_start();
66
67        let trimmed_str_start_pointer = trimmed_str.as_ptr();
68        let trimmed_str_length = trimmed_str.len();
69
70        unsafe {
71            let v = self.as_mut_vec();
72
73            copy(trimmed_str_start_pointer, v.as_mut_ptr(), trimmed_str_length);
74
75            v.set_len(trimmed_str_length);
76        }
77
78        self.as_str()
79    }
80
81    #[inline]
82    fn trim_end_in_place(&mut self) -> &str {
83        let trimmed_str_length = self.trim_end().len();
84
85        unsafe {
86            self.as_mut_vec().set_len(trimmed_str_length);
87        }
88
89        self.as_str()
90    }
91
92    #[inline]
93    fn trim_matches_in_place(&mut self, pat: char) -> &str {
94        let trimmed_str = self.trim_matches(pat);
95
96        let trimmed_str_start_pointer = trimmed_str.as_ptr();
97        let trimmed_str_length = trimmed_str.len();
98
99        unsafe {
100            let v = self.as_mut_vec();
101
102            copy(trimmed_str_start_pointer, v.as_mut_ptr(), trimmed_str_length);
103
104            v.set_len(trimmed_str_length);
105        }
106
107        self.as_str()
108    }
109
110    #[inline]
111    fn trim_start_matches_in_place(&mut self, pat: char) -> &str {
112        let trimmed_str = self.trim_start_matches(pat);
113
114        let trimmed_str_start_pointer = trimmed_str.as_ptr();
115        let trimmed_str_length = trimmed_str.len();
116
117        unsafe {
118            let v = self.as_mut_vec();
119
120            copy(trimmed_str_start_pointer, v.as_mut_ptr(), trimmed_str_length);
121
122            v.set_len(trimmed_str_length);
123        }
124
125        self.as_str()
126    }
127
128    #[inline]
129    fn trim_end_matches_in_place(&mut self, pat: char) -> &str {
130        let trimmed_str_length = self.trim_end_matches(pat).len();
131
132        unsafe {
133            self.as_mut_vec().set_len(trimmed_str_length);
134        }
135
136        self.as_str()
137    }
138}