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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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: &regex::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 }