annotate rust/hg-core/src/utils.rs @ 52156:e6a44bc91bc2 stable

rust-update: make `update_from_null` respect `worker.numcpu` config option This was overlooked in the original series. This is important for tests (because we run many at once), and for the occasional end user that wants to keep their CPU usage in check. A future series should clean up this `worker` parameter tunelling business by rewriting the config in Rust, but doing so on stable would be a very bad idea.
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 05 Nov 2024 15:21:09 +0100
parents aba622c7dc7e
children f4aede0f01af
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
42767
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
1 // utils module
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
2 //
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
3 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
4 //
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
5 // This software may be used and distributed according to the terms of the
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
6 // GNU General Public License version 2 or any later version.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
7
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
8 //! Contains useful functions, traits, structs, etc. for use in core.
4b3b27d567d5 rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42764
diff changeset
9
46513
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
10 use crate::errors::{HgError, IoErrorContext};
44315
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
11 use crate::utils::hg_path::HgPath;
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
12 use im_rc::ordmap::DiffItem;
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
13 use im_rc::ordmap::OrdMap;
51189
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
14 use itertools::EitherOrBoth;
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
15 use itertools::Itertools;
46653
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
16 use std::cell::Cell;
51189
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
17 use std::cmp::Ordering;
46653
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
18 use std::fmt;
44315
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
19 use std::{io::Write, ops::Deref};
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
20
49672
8e0d823ef182 testing: introduce util function to synchronize concurrent commands on files
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48463
diff changeset
21 pub mod debug;
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
22 pub mod files;
42959
3fe40dd6355d rust-hgpath: add HgPath and HgPathBuf structs to encapsulate handling of paths
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42869
diff changeset
23 pub mod hg_path;
44312
c18dd48cea4a rust-pathauditor: add Rust implementation of the `pathauditor`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44079
diff changeset
24 pub mod path_auditor;
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
25
44079
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
26 /// Useful until rust/issues/56345 is stable
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
27 ///
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
28 /// # Examples
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
29 ///
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
30 /// ```
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
31 /// use crate::hg::utils::find_slice_in_slice;
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
32 ///
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
33 /// let haystack = b"This is the haystack".to_vec();
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
34 /// assert_eq!(find_slice_in_slice(&haystack, b"the"), Some(8));
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
35 /// assert_eq!(find_slice_in_slice(&haystack, b"not here"), None);
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
36 /// ```
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
37 pub fn find_slice_in_slice<T>(slice: &[T], needle: &[T]) -> Option<usize>
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
38 where
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
39 for<'a> &'a [T]: PartialEq,
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
40 {
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
41 slice
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
42 .windows(needle.len())
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
43 .position(|window| window == needle)
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
44 }
191a461d6be6 rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42959
diff changeset
45
42610
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
46 /// Replaces the `from` slice with the `to` slice inside the `buf` slice.
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
47 ///
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
48 /// # Examples
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
49 ///
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
50 /// ```
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
51 /// use crate::hg::utils::replace_slice;
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
52 /// let mut line = b"I hate writing tests!".to_vec();
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
53 /// replace_slice(&mut line, b"hate", b"love");
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
54 /// assert_eq!(
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
55 /// line,
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
56 /// b"I love writing tests!".to_vec()
42851
ce6797ef6eab rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents: 42815
diff changeset
57 /// );
42610
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
58 /// ```
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
59 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
60 where
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
61 T: Clone + PartialEq,
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
62 {
42611
2f760da140ee rust-utils: remove buggy assertion
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42610
diff changeset
63 if buf.len() < from.len() || from.len() != to.len() {
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
64 return;
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
65 }
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
66 for i in 0..=buf.len() - from.len() {
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
67 if buf[i..].starts_with(from) {
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
68 buf[i..(i + from.len())].clone_from_slice(to);
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
69 }
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
70 }
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
71 }
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
72
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
73 pub trait SliceExt {
42610
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
74 fn trim_end(&self) -> &Self;
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
75 fn trim_start(&self) -> &Self;
47977
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
76 fn trim_end_matches(&self, f: impl FnMut(u8) -> bool) -> &Self;
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
77 fn trim_start_matches(&self, f: impl FnMut(u8) -> bool) -> &Self;
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
78 fn trim(&self) -> &Self;
42869
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
79 fn drop_prefix(&self, needle: &Self) -> Option<&Self>;
46557
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
80 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>;
47989
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents: 47977
diff changeset
81 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])>;
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
82 }
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
83
47977
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
84 impl SliceExt for [u8] {
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
85 fn trim_end(&self) -> &[u8] {
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
86 self.trim_end_matches(|byte| byte.is_ascii_whitespace())
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
87 }
42453
9609430d3625 rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
88
47977
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
89 fn trim_start(&self) -> &[u8] {
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
90 self.trim_start_matches(|byte| byte.is_ascii_whitespace())
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
91 }
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
92
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
93 fn trim_end_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self {
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
94 if let Some(last) = self.iter().rposition(|&byte| !f(byte)) {
46708
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46653
diff changeset
95 &self[..=last]
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46653
diff changeset
96 } else {
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46653
diff changeset
97 &[]
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46653
diff changeset
98 }
e8cd519a0a34 rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents: 46653
diff changeset
99 }
47977
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
100
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
101 fn trim_start_matches(&self, mut f: impl FnMut(u8) -> bool) -> &Self {
696abab107b4 rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents: 46755
diff changeset
102 if let Some(first) = self.iter().position(|&byte| !f(byte)) {
42610
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
103 &self[first..]
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
104 } else {
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
105 &[]
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
106 }
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
107 }
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
108
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
109 /// ```
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
110 /// use hg::utils::SliceExt;
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
111 /// assert_eq!(
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
112 /// b" to trim ".trim(),
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
113 /// b"to trim"
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
114 /// );
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
115 /// assert_eq!(
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
116 /// b"to trim ".trim(),
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
117 /// b"to trim"
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
118 /// );
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
119 /// assert_eq!(
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
120 /// b" to trim".trim(),
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
121 /// b"to trim"
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
122 /// );
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
123 /// ```
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
124 fn trim(&self) -> &[u8] {
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
125 self.trim_start().trim_end()
5672bb73f61e rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
126 }
42869
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
127
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
128 fn drop_prefix(&self, needle: &Self) -> Option<&Self> {
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
129 if self.starts_with(needle) {
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
130 Some(&self[needle.len()..])
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
131 } else {
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
132 None
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
133 }
62eabdf91f85 rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents: 42851
diff changeset
134 }
46557
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
135
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
136 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])> {
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
137 let mut iter = self.splitn(2, |&byte| byte == separator);
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
138 let a = iter.next()?;
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
139 let b = iter.next()?;
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
140 Some((a, b))
a25033eb43b5 rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents: 46542
diff changeset
141 }
47989
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents: 47977
diff changeset
142
4d2a5ca060e3 rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents: 47977
diff changeset
143 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])> {
50003
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50002
diff changeset
144 find_slice_in_slice(self, separator)
e98fd81bb151 rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50002
diff changeset
145 .map(|pos| (&self[..pos], &self[pos + separator.len()..]))
48463
5734b03ecf3e rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents: 47989
diff changeset
146 }
5734b03ecf3e rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents: 47989
diff changeset
147 }
5734b03ecf3e rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents: 47989
diff changeset
148
44315
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
149 pub trait Escaped {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
150 /// Return bytes escaped for display to the user
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
151 fn escaped_bytes(&self) -> Vec<u8>;
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
152 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
153
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
154 impl Escaped for u8 {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
155 fn escaped_bytes(&self) -> Vec<u8> {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
156 let mut acc = vec![];
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
157 match self {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
158 c @ b'\'' | c @ b'\\' => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
159 acc.push(b'\\');
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
160 acc.push(*c);
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
161 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
162 b'\t' => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
163 acc.extend(br"\\t");
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
164 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
165 b'\n' => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
166 acc.extend(br"\\n");
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
167 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
168 b'\r' => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
169 acc.extend(br"\\r");
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
170 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
171 c if (*c < b' ' || *c >= 127) => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
172 write!(acc, "\\x{:x}", self).unwrap();
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
173 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
174 c => {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
175 acc.push(*c);
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
176 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
177 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
178 acc
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
179 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
180 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
181
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
182 impl<'a, T: Escaped> Escaped for &'a [T] {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
183 fn escaped_bytes(&self) -> Vec<u8> {
44998
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44315
diff changeset
184 self.iter().flat_map(Escaped::escaped_bytes).collect()
44315
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
185 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
186 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
187
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
188 impl<T: Escaped> Escaped for Vec<T> {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
189 fn escaped_bytes(&self) -> Vec<u8> {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
190 self.deref().escaped_bytes()
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
191 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
192 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
193
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
194 impl<'a> Escaped for &'a HgPath {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
195 fn escaped_bytes(&self) -> Vec<u8> {
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
196 self.as_bytes().escaped_bytes()
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
197 }
aa0fc32ece9e rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44312
diff changeset
198 }
46091
9eb07ab3f2d4 rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents: 44998
diff changeset
199
46640
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
200 #[cfg(unix)]
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
201 pub fn shell_quote(value: &[u8]) -> Vec<u8> {
49752
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
202 if value.iter().all(|&byte| {
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
203 matches!(
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
204 byte,
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
205 b'a'..=b'z'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
206 | b'A'..=b'Z'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
207 | b'0'..=b'9'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
208 | b'.'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
209 | b'_'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
210 | b'/'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
211 | b'+'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
212 | b'-'
ec399ddf6764 rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49751
diff changeset
213 )
46640
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
214 }) {
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
215 value.to_owned()
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
216 } else {
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
217 let mut quoted = Vec::with_capacity(value.len() + 2);
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
218 quoted.push(b'\'');
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
219 for &byte in value {
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
220 if byte == b'\'' {
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
221 quoted.push(b'\\');
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
222 }
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
223 quoted.push(byte);
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
224 }
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
225 quoted.push(b'\'');
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
226 quoted
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
227 }
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
228 }
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46625
diff changeset
229
46513
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
230 pub fn current_dir() -> Result<std::path::PathBuf, HgError> {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
231 std::env::current_dir().map_err(|error| HgError::IoError {
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
232 error,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
233 context: IoErrorContext::CurrentDir,
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
234 })
ca3f73cc3cf4 rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents: 46091
diff changeset
235 }
46542
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
236
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
237 pub fn current_exe() -> Result<std::path::PathBuf, HgError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
238 std::env::current_exe().map_err(|error| HgError::IoError {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
239 error,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
240 context: IoErrorContext::CurrentExe,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
241 })
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46513
diff changeset
242 }
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
243
46755
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
244 /// Expand `$FOO` and `${FOO}` environment variables in the given byte string
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
245 pub fn expand_vars(s: &[u8]) -> std::borrow::Cow<[u8]> {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
246 lazy_static::lazy_static! {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
247 /// https://github.com/python/cpython/blob/3.9/Lib/posixpath.py#L301
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
248 /// The `x` makes whitespace ignored.
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
249 /// `-u` disables the Unicode flag, which makes `\w` like Python with the ASCII flag.
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
250 static ref VAR_RE: regex::bytes::Regex =
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
251 regex::bytes::Regex::new(r"(?x-u)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
252 \$
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
253 (?:
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
254 (\w+)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
255 |
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
256 \{
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
257 ([^}]*)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
258 \}
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
259 )
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
260 ").unwrap();
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
261 }
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
262 VAR_RE.replace_all(s, |captures: &regex::bytes::Captures| {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
263 let var_name = files::get_os_str_from_bytes(
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
264 captures
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
265 .get(1)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
266 .or_else(|| captures.get(2))
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
267 .expect("either side of `|` must participate in match")
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
268 .as_bytes(),
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
269 );
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
270 std::env::var_os(var_name)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
271 .map(files::get_bytes_from_os_str)
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
272 .unwrap_or_else(|| {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
273 // Referencing an environment variable that does not exist.
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
274 // Leave the $FOO reference as-is.
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
275 captures[0].to_owned()
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
276 })
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
277 })
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
278 }
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
279
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
280 #[test]
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
281 fn test_expand_vars() {
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
282 // Modifying process-global state in a test isn’t great,
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
283 // but hopefully this won’t collide with anything.
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
284 std::env::set_var("TEST_EXPAND_VAR", "1");
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
285 assert_eq!(
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
286 expand_vars(b"before/$TEST_EXPAND_VAR/after"),
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
287 &b"before/1/after"[..]
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
288 );
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
289 assert_eq!(
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
290 expand_vars(b"before${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}${TEST_EXPAND_VAR}after"),
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
291 &b"before111after"[..]
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
292 );
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
293 let s = b"before $SOME_LONG_NAME_THAT_WE_ASSUME_IS_NOT_AN_ACTUAL_ENV_VAR after";
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
294 assert_eq!(expand_vars(s), &s[..]);
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
295 }
91ab5190a3de rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents: 46708
diff changeset
296
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
297 pub(crate) enum MergeResult<V> {
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
298 Left,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
299 Right,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
300 New(V),
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
301 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
302
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
303 /// Return the union of the two given maps,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
304 /// calling `merge(key, left_value, right_value)` to resolve keys that exist in
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
305 /// both.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
306 ///
50449
331a3cbe1c9e rustdoc: fixed warnings about links
Georges Racinet <georges.racinet@octobus.net>
parents: 50321
diff changeset
307 /// CC <https://github.com/bodil/im-rs/issues/166>
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
308 pub(crate) fn ordmap_union_with_merge<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
309 left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
310 right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
311 mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
312 ) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
313 where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
314 K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
315 V: Clone + PartialEq,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
316 {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
317 if left.ptr_eq(&right) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
318 // One of the two maps is an unmodified clone of the other
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
319 left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
320 } else if left.len() / 2 > right.len() {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
321 // When two maps have different sizes,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
322 // their size difference is a lower bound on
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
323 // how many keys of the larger map are not also in the smaller map.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
324 // This in turn is a lower bound on the number of differences in
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
325 // `OrdMap::diff` and the "amount of work" that would be done
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
326 // by `ordmap_union_with_merge_by_diff`.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
327 //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
328 // Here `left` is more than twice the size of `right`,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
329 // so the number of differences is more than the total size of
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
330 // `right`. Therefore an algorithm based on iterating `right`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
331 // is more efficient.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
332 //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
333 // This helps a lot when a tiny (or empty) map is merged
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
334 // with a large one.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
335 ordmap_union_with_merge_by_iter(left, right, merge)
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
336 } else if left.len() < right.len() / 2 {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
337 // Same as above but with `left` and `right` swapped
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
338 ordmap_union_with_merge_by_iter(right, left, |key, a, b| {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
339 // Also swapped in `merge` arguments:
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
340 match merge(key, b, a) {
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
341 MergeResult::New(v) => MergeResult::New(v),
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
342 // … and swap back in `merge` result:
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
343 MergeResult::Left => MergeResult::Right,
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
344 MergeResult::Right => MergeResult::Left,
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
345 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
346 })
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
347 } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
348 // For maps of similar size, use the algorithm based on `OrdMap::diff`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
349 ordmap_union_with_merge_by_diff(left, right, merge)
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
350 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
351 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
352
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
353 /// Efficient if `right` is much smaller than `left`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
354 fn ordmap_union_with_merge_by_iter<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
355 mut left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
356 right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
357 mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
358 ) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
359 where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
360 K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
361 V: Clone,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
362 {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
363 for (key, right_value) in right {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
364 match left.get(&key) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
365 None => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
366 left.insert(key, right_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
367 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
368 Some(left_value) => match merge(&key, left_value, &right_value) {
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
369 MergeResult::Left => {}
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
370 MergeResult::Right => {
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
371 left.insert(key, right_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
372 }
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
373 MergeResult::New(new_value) => {
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
374 left.insert(key, new_value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
375 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
376 },
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
377 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
378 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
379 left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
380 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
381
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
382 /// Fallback when both maps are of similar size
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
383 fn ordmap_union_with_merge_by_diff<K, V>(
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
384 mut left: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
385 mut right: OrdMap<K, V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
386 mut merge: impl FnMut(&K, &V, &V) -> MergeResult<V>,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
387 ) -> OrdMap<K, V>
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
388 where
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
389 K: Clone + Ord,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
390 V: Clone + PartialEq,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
391 {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
392 // (key, value) pairs that would need to be inserted in either map
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
393 // in order to turn it into the union.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
394 //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
395 // TODO: if/when https://github.com/bodil/im-rs/pull/168 is accepted,
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
396 // change these from `Vec<(K, V)>` to `Vec<(&K, Cow<V>)>`
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
397 // with `left_updates` only borrowing from `right` and `right_updates` from
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
398 // `left`, and with `Cow::Owned` used for `MergeResult::New`.
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
399 //
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
400 // This would allow moving all `.clone()` calls to after we’ve decided
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
401 // which of `right_updates` or `left_updates` to use
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
402 // (value ones becoming `Cow::into_owned`),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
403 // and avoid making clones we don’t end up using.
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
404 let mut left_updates = Vec::new();
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
405 let mut right_updates = Vec::new();
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
406
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
407 for difference in left.diff(&right) {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
408 match difference {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
409 DiffItem::Add(key, value) => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
410 left_updates.push((key.clone(), value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
411 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
412 DiffItem::Remove(key, value) => {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
413 right_updates.push((key.clone(), value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
414 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
415 DiffItem::Update {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
416 old: (key, left_value),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
417 new: (_, right_value),
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
418 } => match merge(key, left_value, right_value) {
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
419 MergeResult::Left => {
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
420 right_updates.push((key.clone(), left_value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
421 }
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
422 MergeResult::Right => {
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
423 left_updates.push((key.clone(), right_value.clone()))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
424 }
50007
83437ad8fe3d rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50003
diff changeset
425 MergeResult::New(new_value) => {
46625
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
426 left_updates.push((key.clone(), new_value.clone()));
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
427 right_updates.push((key.clone(), new_value))
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
428 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
429 },
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
430 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
431 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
432 if left_updates.len() < right_updates.len() {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
433 for (key, value) in left_updates {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
434 left.insert(key, value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
435 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
436 left
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
437 } else {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
438 for (key, value) in right_updates {
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
439 right.insert(key, value);
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
440 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
441 right
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
442 }
435d9fc72646 copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents: 46557
diff changeset
443 }
46653
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
444
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
445 /// Join items of the iterable with the given separator, similar to Python’s
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
446 /// `separator.join(iter)`.
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
447 ///
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
448 /// Formatting the return value consumes the iterator.
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
449 /// Formatting it again will produce an empty string.
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
450 pub fn join_display(
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
451 iter: impl IntoIterator<Item = impl fmt::Display>,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
452 separator: impl fmt::Display,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
453 ) -> impl fmt::Display {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
454 JoinDisplay {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
455 iter: Cell::new(Some(iter.into_iter())),
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
456 separator,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
457 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
458 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
459
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
460 struct JoinDisplay<I, S> {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
461 iter: Cell<Option<I>>,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
462 separator: S,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
463 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
464
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
465 impl<I, T, S> fmt::Display for JoinDisplay<I, S>
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
466 where
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
467 I: Iterator<Item = T>,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
468 T: fmt::Display,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
469 S: fmt::Display,
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
470 {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
471 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
472 if let Some(mut iter) = self.iter.take() {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
473 if let Some(first) = iter.next() {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
474 first.fmt(f)?;
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
475 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
476 for value in iter {
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
477 self.separator.fmt(f)?;
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
478 value.fmt(f)?;
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
479 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
480 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
481 Ok(())
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
482 }
a069639783a0 rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents: 46640
diff changeset
483 }
50035
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
484
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
485 /// Like `Iterator::filter_map`, but over a fallible iterator of `Result`s.
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
486 ///
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
487 /// The callback is only called for incoming `Ok` values. Errors are passed
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
488 /// through as-is. In order to let it use the `?` operator the callback is
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
489 /// expected to return a `Result` of `Option`, instead of an `Option` of
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
490 /// `Result`.
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
491 pub fn filter_map_results<'a, I, F, A, B, E>(
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
492 iter: I,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
493 f: F,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
494 ) -> impl Iterator<Item = Result<B, E>> + 'a
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
495 where
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
496 I: Iterator<Item = Result<A, E>> + 'a,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
497 F: Fn(A) -> Result<Option<B>, E> + 'a,
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
498 {
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
499 iter.filter_map(move |result| match result {
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
500 Ok(node) => f(node).transpose(),
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
501 Err(e) => Some(Err(e)),
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
502 })
f5b168979626 rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50007
diff changeset
503 }
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
504
51189
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
505 /// Like `itertools::merge_join_by`, but merges fallible iterators.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
506 ///
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
507 /// The callback is only used for Ok values. Errors are passed through as-is.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
508 /// Errors compare less than Ok values, which makes the error handling
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
509 /// conservative.
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
510 pub fn merge_join_results_by<'a, I1, I2, F, A, B, E>(
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
511 iter1: I1,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
512 iter2: I2,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
513 f: F,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
514 ) -> impl Iterator<Item = Result<EitherOrBoth<A, B>, E>> + 'a
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
515 where
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
516 I1: Iterator<Item = Result<A, E>> + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
517 I2: Iterator<Item = Result<B, E>> + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
518 F: FnMut(&A, &B) -> Ordering + 'a,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
519 {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
520 let mut g = f;
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
521 iter1
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
522 .merge_join_by(iter2, move |i1, i2| match i1 {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
523 Err(_) => Ordering::Less,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
524 Ok(i1) => match i2 {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
525 Err(_) => Ordering::Greater,
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
526 Ok(i2) => g(i1, i2),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
527 },
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
528 })
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
529 .map(|result| match result {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
530 EitherOrBoth::Left(Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
531 EitherOrBoth::Right(Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
532 EitherOrBoth::Both(Err(e), _) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
533 EitherOrBoth::Both(_, Err(e)) => Err(e),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
534 EitherOrBoth::Left(Ok(v)) => Ok(EitherOrBoth::Left(v)),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
535 EitherOrBoth::Right(Ok(v)) => Ok(EitherOrBoth::Right(v)),
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
536 EitherOrBoth::Both(Ok(v1), Ok(v2)) => {
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
537 Ok(EitherOrBoth::Both(v1, v2))
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
538 }
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
539 })
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
540 }
aba622c7dc7e rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50449
diff changeset
541
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
542 /// Force the global rayon threadpool to not exceed 16 concurrent threads
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
543 /// unless the user has specified a value.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
544 /// This is a stop-gap measure until we figure out why using more than 16
52156
e6a44bc91bc2 rust-update: make `update_from_null` respect `worker.numcpu` config option
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51189
diff changeset
545 /// threads makes `status` and `update` slower for each additional thread.
50321
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
546 ///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
547 /// TODO find the underlying cause and fix it, then remove this.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
548 ///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
549 /// # Errors
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
550 ///
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
551 /// Returns an error if the global threadpool has already been initialized if
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
552 /// we try to initialize it.
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
553 pub fn cap_default_rayon_threads() -> Result<(), rayon::ThreadPoolBuildError> {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
554 const THREAD_CAP: usize = 16;
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
555
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
556 if std::env::var("RAYON_NUM_THREADS").is_err() {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
557 let available_parallelism = std::thread::available_parallelism()
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
558 .map(usize::from)
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
559 .unwrap_or(1);
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
560 let new_thread_count = THREAD_CAP.min(available_parallelism);
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
561 let res = rayon::ThreadPoolBuilder::new()
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
562 .num_threads(new_thread_count)
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
563 .build_global();
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
564 if res.is_ok() {
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
565 log::trace!(
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
566 "Capped the rayon threadpool to {new_thread_count} threads",
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
567 );
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
568 }
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
569 return res;
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
570 }
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
571 Ok(())
14b57943ae6d rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50252
diff changeset
572 }