Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/utils/strings.rs @ 52760:94e2547e6f3d
rust: move code from utils to utils::strings
This moves string-related functions in hg::utils into the recently added
hg::utils::strings module.
author | Mitchell Kember <mkember@janestreet.com> |
---|---|
date | Thu, 16 Jan 2025 13:15:02 -0500 |
parents | 36d39726c0af |
children | 874c64e041b5 |
rev | line source |
---|---|
52760
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
1 //! Contains string-related utilities. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
2 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
3 use crate::utils::hg_path::HgPath; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
4 use std::{cell::Cell, fmt, io::Write as _, ops::Deref as _}; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
5 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
6 /// Useful until rust/issues/56345 is stable |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
7 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
8 /// # Examples |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
9 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
10 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
11 /// use hg::utils::strings::find_slice_in_slice; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
12 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
13 /// let haystack = b"This is the haystack".to_vec(); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
14 /// assert_eq!(find_slice_in_slice(&haystack, b"the"), Some(8)); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
15 /// assert_eq!(find_slice_in_slice(&haystack, b"not here"), None); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
16 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
17 pub fn find_slice_in_slice<T>(slice: &[T], needle: &[T]) -> Option<usize> |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
18 where |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
19 for<'a> &'a [T]: PartialEq, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
20 { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
21 slice |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
22 .windows(needle.len()) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
23 .position(|window| window == needle) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
24 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
25 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
26 /// Replaces the `from` slice with the `to` slice inside the `buf` slice. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
27 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
28 /// # Examples |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
29 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
30 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
31 /// use hg::utils::strings::replace_slice; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
32 /// let mut line = b"I hate writing tests!".to_vec(); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
33 /// replace_slice(&mut line, b"hate", b"love"); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
34 /// assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
35 /// line, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
36 /// b"I love writing tests!".to_vec() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
37 /// ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
38 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
39 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T]) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
40 where |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
41 T: Clone + PartialEq, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
42 { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
43 if buf.len() < from.len() || from.len() != to.len() { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
44 return; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
45 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
46 for i in 0..=buf.len() - from.len() { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
47 if buf[i..].starts_with(from) { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
48 buf[i..(i + from.len())].clone_from_slice(to); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
49 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
50 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
51 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
52 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
53 pub trait SliceExt { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
54 fn trim_end(&self) -> &Self; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
55 fn trim_start(&self) -> &Self; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
56 fn trim_end_matches(&self, f: impl FnMut(u8) -> bool) -> &Self; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
57 fn trim_start_matches(&self, f: impl FnMut(u8) -> bool) -> &Self; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
58 fn trim(&self) -> &Self; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
59 fn drop_prefix(&self, needle: &Self) -> Option<&Self>; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
60 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
61 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])>; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
62 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
63 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
64 impl SliceExt for [u8] { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
65 fn trim_end(&self) -> &[u8] { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
66 self.trim_end_matches(|byte| byte.is_ascii_whitespace()) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
67 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
68 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
69 fn trim_start(&self) -> &[u8] { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
70 self.trim_start_matches(|byte| byte.is_ascii_whitespace()) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
71 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
72 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
73 fn trim_end_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
74 if let Some(last) = self.iter().rposition(|&byte| !f(byte)) { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
75 &self[..=last] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
76 } else { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
77 &[] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
78 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
79 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
80 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
81 fn trim_start_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
82 if let Some(first) = self.iter().position(|&byte| !f(byte)) { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
83 &self[first..] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
84 } else { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
85 &[] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
86 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
87 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
88 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
89 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
90 /// use hg::utils::strings::SliceExt; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
91 /// assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
92 /// b" to trim ".trim(), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
93 /// b"to trim" |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
94 /// ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
95 /// assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
96 /// b"to trim ".trim(), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
97 /// b"to trim" |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
98 /// ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
99 /// assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
100 /// b" to trim".trim(), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
101 /// b"to trim" |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
102 /// ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
103 /// ``` |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
104 fn trim(&self) -> &[u8] { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
105 self.trim_start().trim_end() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
106 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
107 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
108 fn drop_prefix(&self, needle: &Self) -> Option<&Self> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
109 if self.starts_with(needle) { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
110 Some(&self[needle.len()..]) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
111 } else { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
112 None |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
113 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
114 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
115 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
116 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
117 let pos = memchr::memchr(separator, self)?; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
118 Some((&self[..pos], &self[pos + 1..])) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
119 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
120 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
121 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
122 find_slice_in_slice(self, separator) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
123 .map(|pos| (&self[..pos], &self[pos + separator.len()..])) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
124 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
125 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
126 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
127 pub trait Escaped { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
128 /// Return bytes escaped for display to the user |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
129 fn escaped_bytes(&self) -> Vec<u8>; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
130 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
131 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
132 impl Escaped for u8 { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
133 fn escaped_bytes(&self) -> Vec<u8> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
134 let mut acc = vec![]; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
135 match self { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
136 c @ b'\'' | c @ b'\\' => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
137 acc.push(b'\\'); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
138 acc.push(*c); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
139 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
140 b'\t' => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
141 acc.extend(br"\\t"); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
142 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
143 b'\n' => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
144 acc.extend(br"\\n"); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
145 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
146 b'\r' => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
147 acc.extend(br"\\r"); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
148 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
149 c if (*c < b' ' || *c >= 127) => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
150 write!(acc, "\\x{:x}", self).unwrap(); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
151 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
152 c => { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
153 acc.push(*c); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
154 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
155 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
156 acc |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
157 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
158 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
159 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
160 impl<'a, T: Escaped> Escaped for &'a [T] { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
161 fn escaped_bytes(&self) -> Vec<u8> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
162 self.iter().flat_map(Escaped::escaped_bytes).collect() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
163 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
164 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
165 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
166 impl<T: Escaped> Escaped for Vec<T> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
167 fn escaped_bytes(&self) -> Vec<u8> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
168 self.deref().escaped_bytes() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
169 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
170 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
171 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
172 impl<'a> Escaped for &'a HgPath { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
173 fn escaped_bytes(&self) -> Vec<u8> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
174 self.as_bytes().escaped_bytes() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
175 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
176 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
177 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
178 #[cfg(unix)] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
179 pub fn shell_quote(value: &[u8]) -> Vec<u8> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
180 if value.iter().all(|&byte| { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
181 matches!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
182 byte, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
183 b'a'..=b'z' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
184 | b'A'..=b'Z' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
185 | b'0'..=b'9' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
186 | b'.' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
187 | b'_' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
188 | b'/' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
189 | b'+' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
190 | b'-' |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
191 ) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
192 }) { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
193 value.to_owned() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
194 } else { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
195 let mut quoted = Vec::with_capacity(value.len() + 2); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
196 quoted.push(b'\''); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
197 for &byte in value { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
198 if byte == b'\'' { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
199 quoted.push(b'\\'); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
200 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
201 quoted.push(byte); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
202 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
203 quoted.push(b'\''); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
204 quoted |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
205 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
206 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
207 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
208 /// Expand `$FOO` and `${FOO}` environment variables in the given byte string |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
209 pub fn expand_vars(s: &[u8]) -> std::borrow::Cow<[u8]> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
210 lazy_static::lazy_static! { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
211 /// https://github.com/python/cpython/blob/3.9/Lib/posixpath.py#L301 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
212 /// The `x` makes whitespace ignored. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
213 /// `-u` disables the Unicode flag, which makes `\w` like Python with the ASCII flag. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
214 static ref VAR_RE: regex::bytes::Regex = |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
215 regex::bytes::Regex::new(r"(?x-u) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
216 \$ |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
217 (?: |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
218 (\w+) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
219 | |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
220 \{ |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
221 ([^}]*) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
222 \} |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
223 ) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
224 ").unwrap(); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
225 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
226 VAR_RE.replace_all(s, |captures: ®ex::bytes::Captures| { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
227 let var_name = crate::utils::files::get_os_str_from_bytes( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
228 captures |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
229 .get(1) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
230 .or_else(|| captures.get(2)) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
231 .expect("either side of `|` must participate in match") |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
232 .as_bytes(), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
233 ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
234 std::env::var_os(var_name) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
235 .map(crate::utils::files::get_bytes_from_os_str) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
236 .unwrap_or_else(|| { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
237 // Referencing an environment variable that does not exist. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
238 // Leave the $FOO reference as-is. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
239 captures[0].to_owned() |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
240 }) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
241 }) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
242 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
243 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
244 /// Join items of the iterable with the given separator, similar to Python’s |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
245 /// `separator.join(iter)`. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
246 /// |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
247 /// Formatting the return value consumes the iterator. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
248 /// Formatting it again will produce an empty string. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
249 pub fn join_display( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
250 iter: impl IntoIterator<Item = impl fmt::Display>, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
251 separator: impl fmt::Display, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
252 ) -> impl fmt::Display { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
253 JoinDisplay { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
254 iter: Cell::new(Some(iter.into_iter())), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
255 separator, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
256 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
257 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
258 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
259 struct JoinDisplay<I, S> { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
260 iter: Cell<Option<I>>, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
261 separator: S, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
262 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
263 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
264 impl<I, T, S> fmt::Display for JoinDisplay<I, S> |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
265 where |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
266 I: Iterator<Item = T>, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
267 T: fmt::Display, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
268 S: fmt::Display, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
269 { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
271 if let Some(mut iter) = self.iter.take() { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
272 if let Some(first) = iter.next() { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
273 first.fmt(f)?; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
274 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
275 for value in iter { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
276 self.separator.fmt(f)?; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
277 value.fmt(f)?; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
278 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
279 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
280 Ok(()) |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
281 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
282 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
283 |
52759
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
284 /// Returns a short representation of a user name or email address. |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
285 pub fn short_user(user: &[u8]) -> &[u8] { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
286 let mut str = user; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
287 if let Some(i) = memchr::memchr(b'@', str) { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
288 str = &str[..i]; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
289 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
290 if let Some(i) = memchr::memchr(b'<', str) { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
291 str = &str[i + 1..]; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
292 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
293 if let Some(i) = memchr::memchr(b' ', str) { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
294 str = &str[..i]; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
295 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
296 if let Some(i) = memchr::memchr(b'.', str) { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
297 str = &str[..i]; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
298 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
299 str |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
300 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
301 |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
302 #[cfg(test)] |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
303 mod tests { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
304 use super::*; |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
305 |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
306 #[test] |
52760
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
307 fn test_expand_vars() { |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
308 // Modifying process-global state in a test isn’t great, |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
309 // but hopefully this won’t collide with anything. |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
310 std::env::set_var("TEST_EXPAND_VAR", "1"); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
311 assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
312 expand_vars(b"before/$TEST_EXPAND_VAR/after"), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
313 &b"before/1/after"[..] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
314 ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
315 assert_eq!( |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
316 expand_vars(b"before${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}after"), |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
317 &b"before111after"[..] |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
318 ); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
319 let s = b"before $SOME_LONG_NAME_THAT_WE_ASSUME_IS_NOT_AN_ACTUAL_ENV_VAR after"; |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
320 assert_eq!(expand_vars(s), &s[..]); |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
321 } |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
322 |
94e2547e6f3d
rust: move code from utils to utils::strings
Mitchell Kember <mkember@janestreet.com>
parents:
52759
diff
changeset
|
323 #[test] |
52759
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
324 fn test_short_user() { |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
325 assert_eq!(short_user(b""), b""); |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
326 assert_eq!(short_user(b"Name"), b"Name"); |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
327 assert_eq!(short_user(b"First Last"), b"First"); |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
328 assert_eq!(short_user(b"First Last <user@example.com>"), b"user"); |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
329 assert_eq!(short_user(b"First Last <user.name@example.com>"), b"user"); |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
330 } |
36d39726c0af
rust: add utils::strings module
Mitchell Kember <mkember@janestreet.com>
parents:
diff
changeset
|
331 } |