Squashed 'third_party/rules_rust/' content from commit bf59038ca
git-subtree-dir: third_party/rules_rust
git-subtree-split: bf59038cac11798cbaef9f3bf965bad8182b97fa
Signed-off-by: Brian Silverman <bsilver16384@gmail.com>
Change-Id: I5a20e403203d670df467ea97dde9a4ac40339a8d
diff --git a/util/process_wrapper/util.rs b/util/process_wrapper/util.rs
new file mode 100644
index 0000000..4b3d6bb
--- /dev/null
+++ b/util/process_wrapper/util.rs
@@ -0,0 +1,103 @@
+// Copyright 2020 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use std::fs::File;
+use std::io::{BufRead, BufReader, Read};
+
+pub(crate) fn read_file_to_array(path: String) -> Result<Vec<String>, String> {
+ let file = File::open(path).map_err(|e| e.to_string())?;
+ read_to_array(file)
+}
+
+pub(crate) fn read_stamp_status_to_array(path: String) -> Result<Vec<(String, String)>, String> {
+ let file = File::open(path).map_err(|e| e.to_string())?;
+ stamp_status_to_array(file)
+}
+
+fn read_to_array(reader: impl Read) -> Result<Vec<String>, String> {
+ let reader = BufReader::new(reader);
+ let mut ret = vec![];
+ let mut escaped_line = String::new();
+ for l in reader.lines() {
+ let line = l.map_err(|e| e.to_string())?;
+ if line.is_empty() {
+ continue;
+ }
+ // a \ at the end of a line allows us to escape the new line break,
+ // \\ yields a single \, so \\\ translates to a single \ and a new line
+ // escape
+ let end_backslash_count = line.chars().rev().take_while(|&c| c == '\\').count();
+ // a 0 or even number of backslashes do not lead to a new line escape
+ let escape = end_backslash_count % 2 == 1;
+ // remove backslashes and add back two for every one
+ let l = line.trim_end_matches('\\');
+ escaped_line.push_str(l);
+ for _ in 0..end_backslash_count / 2 {
+ escaped_line.push('\\');
+ }
+ if escape {
+ // we add a newline as we expect a line after this
+ escaped_line.push('\n');
+ } else {
+ ret.push(escaped_line);
+ escaped_line = String::new();
+ }
+ }
+ Ok(ret)
+}
+
+fn stamp_status_to_array(reader: impl Read) -> Result<Vec<(String, String)>, String> {
+ let escaped_lines = read_to_array(reader)?;
+ escaped_lines
+ .into_iter()
+ .map(|l| {
+ let (s1, s2) = l
+ .split_once(' ')
+ .ok_or_else(|| format!("wrong workspace status file format for \"{}\"", l))?;
+ Ok((s1.to_owned(), s2.to_owned()))
+ })
+ .collect()
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_read_to_array() {
+ let input = r#"some escaped \\\
+string
+with other lines"#
+ .to_owned();
+ let expected = vec![
+ r#"some escaped \
+string"#,
+ "with other lines",
+ ];
+ let got = read_to_array(input.as_bytes()).unwrap();
+ assert_eq!(expected, got);
+ }
+
+ #[test]
+ fn test_stamp_status_to_array() {
+ let lines = "aaa bbb\\\nvvv\nccc ddd\neee fff";
+ let got = stamp_status_to_array(lines.as_bytes()).unwrap();
+ let expected = vec![
+ ("aaa".to_owned(), "bbb\nvvv".to_owned()),
+ ("ccc".to_owned(), "ddd".to_owned()),
+ ("eee".to_owned(), "fff".to_owned()),
+ ];
+ assert_eq!(expected, got);
+ }
+}