str_utils/
replace_newlines_with_space.rs1use alloc::{borrow::Cow, vec::Vec};
2
3pub trait ReplaceNewlinesWithSpace<'a> {
7 fn replace_newlines_with_space(self) -> Cow<'a, str>;
11}
12
13impl<'a> ReplaceNewlinesWithSpace<'a> for &'a str {
14 fn replace_newlines_with_space(self) -> Cow<'a, str> {
15 let s = self;
16 let bytes = s.as_bytes();
17 let length = bytes.len();
18
19 let mut p = 0;
20
21 let first_len = loop {
22 if p == length {
23 return Cow::from(s);
24 }
25
26 let e = bytes[p];
27
28 match e {
29 b'\r' => {
30 if p < length - 1 && bytes[p + 1] == b'\n' {
31 break 2; } else {
33 break 1; }
35 },
36 b'\n' => {
37 break 1; },
39 _ => (),
40 }
41
42 p += 1;
43 };
44
45 let mut new_v = Vec::with_capacity(bytes.len());
46
47 new_v.extend_from_slice(&bytes[..p]);
48 new_v.push(b' ');
49
50 p += first_len;
51
52 let mut start = p;
53
54 loop {
55 if p == length {
56 break;
57 }
58
59 let e = bytes[p];
60
61 match e {
62 b'\r' => {
63 new_v.extend_from_slice(&bytes[start..p]);
64
65 if p < length - 1 && bytes[p + 1] == b'\n' {
66 p += 1;
68 start = p + 1;
69 } else {
70 start = p + 1;
72 }
73
74 new_v.push(b' ');
75 },
76 b'\n' => {
77 new_v.extend_from_slice(&bytes[start..p]);
79 start = p + 1;
80
81 new_v.push(b' ');
82 },
83 _ => (),
84 }
85
86 p += 1;
87 }
88
89 new_v.extend_from_slice(&bytes[start..p]);
90
91 Cow::from(unsafe { String::from_utf8_unchecked(new_v) })
92 }
93}
94
95impl<'a> ReplaceNewlinesWithSpace<'a> for Cow<'a, str> {
96 #[inline]
97 fn replace_newlines_with_space(self) -> Cow<'a, str> {
98 match self {
99 Cow::Borrowed(s) => s.replace_newlines_with_space(),
100 Cow::Owned(s) => {
101 match s.replace_newlines_with_space() {
102 Cow::Borrowed(_) => {
103 Cow::Owned(s)
106 },
107 Cow::Owned(s) => Cow::Owned(s),
108 }
109 },
110 }
111 }
112}