Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/utils.rs @ 52160:e01e84e5e426
rust-revlog: add a Rust-only `InnerRevlog`
This mirrors the Python `InnerRevlog` and will be used in a future patch
to replace said Python implementation. This allows us to start doing more
things in pure Rust, in particular reading and writing operations.
A lot of changes have to be introduced all at once, it wouldn't be very
useful to separate this patch IMO since all of them are either interlocked
or only useful with the rest.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 10 Oct 2024 10:34:51 +0200 |
parents | aba622c7dc7e |
children | e6a44bc91bc2 |
rev | line source |
---|---|
42751
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42748
diff
changeset
|
1 // utils module |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42748
diff
changeset
|
2 // |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42748
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:
42748
diff
changeset
|
4 // |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42748
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:
42748
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:
42748
diff
changeset
|
7 |
4b3b27d567d5
rust-docstrings: add missing module docstrings
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42748
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:
42748
diff
changeset
|
9 |
46445
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
10 use crate::errors::{HgError, IoErrorContext}; |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
11 use crate::utils::hg_path::HgPath; |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
13 use im_rc::ordmap::OrdMap; |
51151
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
14 use itertools::EitherOrBoth; |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
15 use itertools::Itertools; |
46614
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
16 use std::cell::Cell; |
51151
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
17 use std::cmp::Ordering; |
46614
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
18 use std::fmt; |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
19 use std::{io::Write, ops::Deref}; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
20 |
50214
8e0d823ef182
testing: introduce util function to synchronize concurrent commands on files
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48417
diff
changeset
|
21 pub mod debug; |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 pub mod files; |
42956
3fe40dd6355d
rust-hgpath: add HgPath and HgPathBuf structs to encapsulate handling of paths
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42863
diff
changeset
|
23 pub mod hg_path; |
44265
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; |
42437
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:
42956
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:
42956
diff
changeset
|
27 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
28 /// # Examples |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
29 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
30 /// ``` |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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:
42956
diff
changeset
|
32 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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:
42956
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:
42956
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:
42956
diff
changeset
|
36 /// ``` |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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:
42956
diff
changeset
|
38 where |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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:
42956
diff
changeset
|
40 { |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
41 slice |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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:
42956
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:
42956
diff
changeset
|
44 } |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
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() |
42841
ce6797ef6eab
rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents:
42799
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 /// ``` |
42437
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() { |
42437
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; |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
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:
46742
diff
changeset
|
77 fn trim_start_matches(&self, f: impl FnMut(u8) -> bool) -> &Self; |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
78 fn trim(&self) -> &Self; |
42863
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
79 fn drop_prefix(&self, needle: &Self) -> Option<&Self>; |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
80 fn split_2(&self, separator: u8) -> Option<(&[u8], &[u8])>; |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
81 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])>; |
42437
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 |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
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:
46742
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:
46742
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:
46742
diff
changeset
|
87 } |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
88 |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
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:
46742
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:
46742
diff
changeset
|
91 } |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
92 |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
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:
46742
diff
changeset
|
94 if let Some(last) = self.iter().rposition(|&byte| !f(byte)) { |
46669
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
95 &self[..=last] |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
96 } else { |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
97 &[] |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
98 } |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
99 } |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
100 |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
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:
46742
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 } |
42863
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
127 |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
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:
42841
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:
42841
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:
42841
diff
changeset
|
131 } else { |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
132 None |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
133 } |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
134 } |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
135 |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
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:
46483
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:
46483
diff
changeset
|
138 let a = iter.next()?; |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
139 let b = iter.next()?; |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
140 Some((a, b)) |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
141 } |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
142 |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
143 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])> { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49929
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:
49929
diff
changeset
|
145 .map(|pos| (&self[..pos], &self[pos + separator.len()..])) |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
146 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
147 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
148 |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
149 pub trait Escaped { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
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:
44265
diff
changeset
|
151 fn escaped_bytes(&self) -> Vec<u8>; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
152 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
153 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
154 impl Escaped for u8 { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
155 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
156 let mut acc = vec![]; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
157 match self { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
158 c @ b'\'' | c @ b'\\' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
159 acc.push(b'\\'); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
160 acc.push(*c); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
161 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
162 b'\t' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
163 acc.extend(br"\\t"); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
164 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
165 b'\n' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
166 acc.extend(br"\\n"); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
167 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
168 b'\r' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
169 acc.extend(br"\\r"); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
170 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
171 c if (*c < b' ' || *c >= 127) => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
172 write!(acc, "\\x{:x}", self).unwrap(); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
173 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
174 c => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
175 acc.push(*c); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
176 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
177 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
178 acc |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
179 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
180 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
181 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
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:
44265
diff
changeset
|
183 fn escaped_bytes(&self) -> Vec<u8> { |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44268
diff
changeset
|
184 self.iter().flat_map(Escaped::escaped_bytes).collect() |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
185 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
186 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
187 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
188 impl<T: Escaped> Escaped for Vec<T> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
189 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
190 self.deref().escaped_bytes() |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
191 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
192 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
193 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
194 impl<'a> Escaped for &'a HgPath { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
195 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
196 self.as_bytes().escaped_bytes() |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
197 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
198 } |
46090
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
199 |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
200 #[cfg(unix)] |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
201 pub fn shell_quote(value: &[u8]) -> Vec<u8> { |
49634
ec399ddf6764
rust: use `matches!` macro now that we're using Rust 1.42+
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
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:
49633
diff
changeset
|
213 ) |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
214 }) { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
215 value.to_owned() |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
216 } else { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
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:
46586
diff
changeset
|
218 quoted.push(b'\''); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
219 for &byte in value { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
220 if byte == b'\'' { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
221 quoted.push(b'\\'); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
222 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
223 quoted.push(byte); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
224 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
225 quoted.push(b'\''); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
226 quoted |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
227 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
228 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
229 |
46445
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
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:
46090
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:
46090
diff
changeset
|
232 error, |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
233 context: IoErrorContext::CurrentDir, |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
234 }) |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
235 } |
46483
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
236 |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
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:
46445
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:
46445
diff
changeset
|
239 error, |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
240 context: IoErrorContext::CurrentExe, |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
241 }) |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
242 } |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
243 |
46742
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
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:
46669
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:
46669
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:
46669
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:
46669
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:
46669
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:
46669
diff
changeset
|
252 \$ |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
253 (?: |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
254 (\w+) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
255 | |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
256 \{ |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
257 ([^}]*) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
258 \} |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
259 ) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
260 ").unwrap(); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
261 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
262 VAR_RE.replace_all(s, |captures: ®ex::bytes::Captures| { |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
diff
changeset
|
264 captures |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
265 .get(1) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
diff
changeset
|
268 .as_bytes(), |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
269 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
diff
changeset
|
272 .unwrap_or_else(|| { |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
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:
46669
diff
changeset
|
276 }) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
277 }) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
278 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
279 |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
280 #[test] |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
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:
46669
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:
46669
diff
changeset
|
285 assert_eq!( |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
diff
changeset
|
288 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
289 assert_eq!( |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
diff
changeset
|
291 &b"before111after"[..] |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
292 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
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:
46669
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:
46669
diff
changeset
|
295 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
296 |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
297 pub(crate) enum MergeResult<V> { |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
298 Left, |
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
299 Right, |
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
300 New(V), |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
301 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
302 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
305 /// both. |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
306 /// |
50412
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> |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
313 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
316 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
319 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
327 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
332 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
340 match merge(key, b, a) { |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
341 MergeResult::New(v) => MergeResult::New(v), |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
342 // … and swap back in `merge` result: |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
343 MergeResult::Left => MergeResult::Right, |
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
344 MergeResult::Right => MergeResult::Left, |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
345 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
346 }) |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
347 } else { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
350 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
351 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
352 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
359 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
361 V: Clone, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
362 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
365 None => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
367 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
368 Some(left_value) => match merge(&key, left_value, &right_value) { |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
369 MergeResult::Left => {} |
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
370 MergeResult::Right => { |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
372 } |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
373 MergeResult::New(new_value) => { |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
375 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
376 }, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
377 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
378 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
379 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
380 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
381 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
388 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
391 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
394 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
397 // with `left_updates` only borrowing from `right` and `right_updates` from |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
398 // `left`, and with `Cow::Owned` used for `MergeResult::New`. |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
399 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
406 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
408 match difference { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
411 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
414 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
415 DiffItem::Update { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
418 } => match merge(key, left_value, right_value) { |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
419 MergeResult::Left => { |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
421 } |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
422 MergeResult::Right => { |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
diff
changeset
|
424 } |
49934
83437ad8fe3d
rust-clippy: remove redundant suffix from enum
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49930
diff
changeset
|
425 MergeResult::New(new_value) => { |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
428 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
429 }, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
430 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
431 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
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:
46505
diff
changeset
|
435 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
436 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
437 } else { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
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:
46505
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:
46505
diff
changeset
|
440 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
441 right |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
442 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
443 } |
46614
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
444 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
diff
changeset
|
446 /// `separator.join(iter)`. |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
447 /// |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
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:
46601
diff
changeset
|
450 pub fn join_display( |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
diff
changeset
|
452 separator: impl fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
453 ) -> impl fmt::Display { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
454 JoinDisplay { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
diff
changeset
|
456 separator, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
457 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
458 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
459 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
460 struct JoinDisplay<I, S> { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
461 iter: Cell<Option<I>>, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
462 separator: S, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
463 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
464 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
diff
changeset
|
466 where |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
467 I: Iterator<Item = T>, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
468 T: fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
469 S: fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
470 { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
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:
46601
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:
46601
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:
46601
diff
changeset
|
474 first.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
475 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
476 for value in iter { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
477 self.separator.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
478 value.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
479 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
480 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
481 Ok(()) |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
482 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
483 } |
49979
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
diff
changeset
|
484 |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
diff
changeset
|
486 /// |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
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:
49934
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:
49934
diff
changeset
|
490 /// `Result`. |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
diff
changeset
|
492 iter: I, |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
diff
changeset
|
493 f: F, |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
diff
changeset
|
495 where |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
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:
49934
diff
changeset
|
498 { |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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:
49934
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:
49934
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:
49934
diff
changeset
|
502 }) |
f5b168979626
rust: move `filter_map_results` to public util
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49934
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 |
51151
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
diff
changeset
|
506 /// |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
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:
50412
diff
changeset
|
509 /// conservative. |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
diff
changeset
|
511 iter1: I1, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
512 iter2: I2, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
513 f: F, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
diff
changeset
|
515 where |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
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:
50412
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:
50412
diff
changeset
|
519 { |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
520 let mut g = f; |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
521 iter1 |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
diff
changeset
|
523 Err(_) => Ordering::Less, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
524 Ok(i1) => match i2 { |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
525 Err(_) => Ordering::Greater, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
diff
changeset
|
527 }, |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
528 }) |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
529 .map(|result| match result { |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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:
50412
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:
50412
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:
50412
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:
50412
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:
50412
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:
50412
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:
50412
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:
50412
diff
changeset
|
538 } |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
539 }) |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
diff
changeset
|
540 } |
aba622c7dc7e
rust: add a utility function to merge ordered fallible iterators
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
50412
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 |
14b57943ae6d
rust: fix thread cap (for real this time)
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50252
diff
changeset
|
545 /// threads makes `status` slower for each additional thread. |
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 } |