Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/utils.rs @ 49000:dd6b67d5c256 stable
rust: fix unsound `OwningDirstateMap`
As per the previous patch, `OwningDirstateMap` is unsound. Self-referential
structs are difficult to implement correctly in Rust since the compiler is
free to move structs around as much as it wants to. They are also very rarely
needed in practice, so the state-of-the-art on how they should be done within
the Rust rules is still a bit new.
The crate `ouroboros` is an attempt at providing a safe way (in the Rust sense)
of declaring self-referential structs. It is getting a lot attention and was
improved very quickly when soundness issues were found in the past: rather than
relying on our own (limited) review circle, we might as well use the de-facto
common crate to fix this problem. This will give us a much better chance of
finding issues should any new ones be discovered as well as the benefit of
fewer `unsafe` APIs of our own.
I was starting to think about how I would present a safe API to the old struct
but soon realized that the callback-based approach was already done in
`ouroboros`, along with a lot more care towards refusing incorrect structs.
In short: we don't return a mutable reference to the `DirstateMap` anymore, we
expect users of its API to pass a `FnOnce` that takes the map as an argument.
This allows our `OwningDirstateMap` to control the input and output lifetimes
of the code that modifies it to prevent such issues.
Changing to `ouroboros` meant changing every API with it, but it is relatively
low churn in the end. It correctly identified the example buggy modification of
`copy_map_insert` outlined in the previous patch as violating the borrow rules.
Differential Revision: https://phab.mercurial-scm.org/D12429
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Tue, 05 Apr 2022 10:55:28 +0200 |
parents | 5734b03ecf3e |
children | 29cf3167e459 8e0d823ef182 |
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; |
46614
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
14 use std::cell::Cell; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
15 use std::fmt; |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
16 use std::{io::Write, ops::Deref}; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
17 |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 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
|
19 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
|
20 pub mod path_auditor; |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
21 |
44079
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
22 /// 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
|
23 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
24 /// # Examples |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
25 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
26 /// ``` |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
27 /// 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
|
28 /// |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
29 /// 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
|
30 /// 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
|
31 /// 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
|
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 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
|
34 where |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
35 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
|
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 slice |
191a461d6be6
rust-utils: add util to find a slice in another slice
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42956
diff
changeset
|
38 .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
|
39 .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
|
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 |
42610
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
42 /// 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
|
43 /// |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
44 /// # Examples |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
45 /// |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
46 /// ``` |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
47 /// 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
|
48 /// 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
|
49 /// 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
|
50 /// assert_eq!( |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
51 /// line, |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
52 /// b"I love writing tests!".to_vec() |
42841
ce6797ef6eab
rust: apply more formatting fixes
Yuya Nishihara <yuya@tcha.org>
parents:
42799
diff
changeset
|
53 /// ); |
42610
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
54 /// ``` |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
55 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
|
56 where |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
57 T: Clone + PartialEq, |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
58 { |
42611
2f760da140ee
rust-utils: remove buggy assertion
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42610
diff
changeset
|
59 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
|
60 return; |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
61 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
62 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
|
63 if buf[i..].starts_with(from) { |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
64 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
|
65 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
66 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
67 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
68 |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
69 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
|
70 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
|
71 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
|
72 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
|
73 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
|
74 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
|
75 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
|
76 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
|
77 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
|
78 } |
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
79 |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
80 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
|
81 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
|
82 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
|
83 } |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
84 |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
85 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
|
86 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
|
87 } |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
88 |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
89 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
|
90 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
|
91 &self[..=last] |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
92 } else { |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
93 &[] |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
94 } |
e8cd519a0a34
rhg: Ignore trailing newlines in .hg/sharedpath
Simon Sapin <simon.sapin@octobus.net>
parents:
46614
diff
changeset
|
95 } |
47949
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
96 |
696abab107b4
rust: Generalize the `trim_end_newlines` utility of byte strings
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
97 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
|
98 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
|
99 &self[first..] |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
100 } else { |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
101 &[] |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
102 } |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
103 } |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
104 |
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 /// 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
|
107 /// assert_eq!( |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
108 /// 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
|
109 /// b"to trim" |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
110 /// ); |
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 /// ``` |
5672bb73f61e
rust-utils: add docstrings and doctests for utils.rs
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
120 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
|
121 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
|
122 } |
42863
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
123 |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
124 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
|
125 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
|
126 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
|
127 } else { |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
128 None |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
129 } |
62eabdf91f85
rustfilepatterns: refactor the pattern of removing a prefix from a &[u8]
Valentin Gatien-Baron <valentin.gatienbaron@gmail.com>
parents:
42841
diff
changeset
|
130 } |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
131 |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
132 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
|
133 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
|
134 let a = iter.next()?; |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
135 let b = iter.next()?; |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
136 Some((a, b)) |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
137 } |
47961
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
138 |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
139 fn split_2_by_slice(&self, separator: &[u8]) -> Option<(&[u8], &[u8])> { |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
140 if let Some(pos) = find_slice_in_slice(self, separator) { |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
141 Some((&self[..pos], &self[pos + separator.len()..])) |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
142 } else { |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
143 None |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
144 } |
4d2a5ca060e3
rust: Add a Filelog struct that wraps Revlog
Simon Sapin <simon.sapin@octobus.net>
parents:
47949
diff
changeset
|
145 } |
42437
9609430d3625
rust-filepatterns: use bytes instead of String
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
146 } |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
147 |
48417
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
148 pub trait StrExt { |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
149 // TODO: Use https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_once |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
150 // once we require Rust 1.52+ |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
151 fn split_2(&self, separator: char) -> Option<(&str, &str)>; |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
152 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
153 |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
154 impl StrExt for str { |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
155 fn split_2(&self, separator: char) -> Option<(&str, &str)> { |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
156 let mut iter = self.splitn(2, separator); |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
157 let a = iter.next()?; |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
158 let b = iter.next()?; |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
159 Some((a, b)) |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
160 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
161 } |
5734b03ecf3e
rhg: Initial repository locking
Simon Sapin <simon.sapin@octobus.net>
parents:
47961
diff
changeset
|
162 |
44268
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
163 pub trait Escaped { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
164 /// 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
|
165 fn escaped_bytes(&self) -> Vec<u8>; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
166 } |
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 impl Escaped for u8 { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
169 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
170 let mut acc = vec![]; |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
171 match self { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
172 c @ b'\'' | c @ b'\\' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
173 acc.push(b'\\'); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
174 acc.push(*c); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
175 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
176 b'\t' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
177 acc.extend(br"\\t"); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
178 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
179 b'\n' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
180 acc.extend(br"\\n"); |
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 b'\r' => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
183 acc.extend(br"\\r"); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
184 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
185 c if (*c < b' ' || *c >= 127) => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
186 write!(acc, "\\x{:x}", self).unwrap(); |
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 c => { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
189 acc.push(*c); |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
190 } |
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 acc |
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 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
195 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
196 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
|
197 fn escaped_bytes(&self) -> Vec<u8> { |
44973
26114bd6ec60
rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44268
diff
changeset
|
198 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
|
199 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
200 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
201 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
202 impl<T: Escaped> Escaped for Vec<T> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
203 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
204 self.deref().escaped_bytes() |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
205 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
206 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
207 |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
208 impl<'a> Escaped for &'a HgPath { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
209 fn escaped_bytes(&self) -> Vec<u8> { |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
210 self.as_bytes().escaped_bytes() |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
211 } |
aa0fc32ece9e
rust-utils: add `Escaped` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents:
44265
diff
changeset
|
212 } |
46090
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
213 |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
214 // TODO: use the str method when we require Rust 1.45 |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
215 pub(crate) fn strip_suffix<'a>(s: &'a str, suffix: &str) -> Option<&'a str> { |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
216 if s.ends_with(suffix) { |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
217 Some(&s[..s.len() - suffix.len()]) |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
218 } else { |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
219 None |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
220 } |
9eb07ab3f2d4
rhg: use persistent nodemap when available
Simon Sapin <simon-commits@exyr.org>
parents:
44973
diff
changeset
|
221 } |
46445
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
222 |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
223 #[cfg(unix)] |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
224 pub fn shell_quote(value: &[u8]) -> Vec<u8> { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
225 // TODO: Use the `matches!` macro when we require Rust 1.42+ |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
226 if value.iter().all(|&byte| match byte { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
227 b'a'..=b'z' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
228 | b'A'..=b'Z' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
229 | b'0'..=b'9' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
230 | b'.' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
231 | b'_' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
232 | b'/' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
233 | b'+' |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
234 | b'-' => true, |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
235 _ => false, |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
236 }) { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
237 value.to_owned() |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
238 } else { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
239 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
|
240 quoted.push(b'\''); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
241 for &byte in value { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
242 if byte == b'\'' { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
243 quoted.push(b'\\'); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
244 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
245 quoted.push(byte); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
246 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
247 quoted.push(b'\''); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
248 quoted |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
249 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
250 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46586
diff
changeset
|
251 |
46445
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
252 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
|
253 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
|
254 error, |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
255 context: IoErrorContext::CurrentDir, |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
256 }) |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
46090
diff
changeset
|
257 } |
46483
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
258 |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
259 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
|
260 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
|
261 error, |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
262 context: IoErrorContext::CurrentExe, |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
263 }) |
2845892dd489
rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46445
diff
changeset
|
264 } |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
265 |
46742
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
266 /// 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
|
267 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
|
268 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
|
269 /// 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
|
270 /// 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
|
271 /// `-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
|
272 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
|
273 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
|
274 \$ |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
275 (?: |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
276 (\w+) |
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 \} |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
281 ) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
282 ").unwrap(); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
283 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
284 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
|
285 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
|
286 captures |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
287 .get(1) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
288 .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
|
289 .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
|
290 .as_bytes(), |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
291 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
292 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
|
293 .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
|
294 .unwrap_or_else(|| { |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
295 // 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
|
296 // 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
|
297 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
|
298 }) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
299 }) |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
300 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
301 |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
302 #[test] |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
303 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
|
304 // 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
|
305 // 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
|
306 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
|
307 assert_eq!( |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
308 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
|
309 &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
|
310 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
311 assert_eq!( |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
312 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
|
313 &b"before111after"[..] |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
314 ); |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
315 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
|
316 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
|
317 } |
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46669
diff
changeset
|
318 |
46586
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
319 pub(crate) enum MergeResult<V> { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
320 UseLeftValue, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
321 UseRightValue, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
322 UseNewValue(V), |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
323 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
324 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
325 /// 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
|
326 /// 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
|
327 /// both. |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
328 /// |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
329 /// CC https://github.com/bodil/im-rs/issues/166 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
330 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
|
331 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
|
332 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
|
333 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
|
334 ) -> 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
|
335 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
336 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
|
337 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
|
338 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
339 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
|
340 // 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
|
341 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
342 } 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
|
343 // 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
|
344 // 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
|
345 // 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
|
346 // 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
|
347 // `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
|
348 // 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
|
349 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
350 // 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
|
351 // 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
|
352 // `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
|
353 // 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
|
354 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
355 // 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
|
356 // 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
|
357 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
|
358 } 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
|
359 // 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
|
360 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
|
361 // 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
|
362 match merge(key, b, a) { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
363 MergeResult::UseNewValue(v) => MergeResult::UseNewValue(v), |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
364 // … and swap back in `merge` result: |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
365 MergeResult::UseLeftValue => MergeResult::UseRightValue, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
366 MergeResult::UseRightValue => MergeResult::UseLeftValue, |
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 }) |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
369 } else { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
370 // 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
|
371 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
|
372 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
373 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
374 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
375 /// 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
|
376 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
|
377 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
|
378 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
|
379 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
|
380 ) -> 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
|
381 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
382 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
|
383 V: Clone, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
384 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
385 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
|
386 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
|
387 None => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
388 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
|
389 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
390 Some(left_value) => match merge(&key, left_value, &right_value) { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
391 MergeResult::UseLeftValue => {} |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
392 MergeResult::UseRightValue => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
393 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
|
394 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
395 MergeResult::UseNewValue(new_value) => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
396 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
|
397 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
398 }, |
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 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
401 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
402 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
403 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
404 /// 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
|
405 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
|
406 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
|
407 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
|
408 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
|
409 ) -> 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
|
410 where |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
411 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
|
412 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
|
413 { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
414 // (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
|
415 // 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
|
416 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
417 // 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
|
418 // 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
|
419 // with `left_updates` only borrowing from `right` and `right_updates` from |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
420 // `left`, and with `Cow::Owned` used for `MergeResult::UseNewValue`. |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
421 // |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
422 // 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
|
423 // 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
|
424 // (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
|
425 // 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
|
426 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
|
427 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
|
428 |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
429 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
|
430 match difference { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
431 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
|
432 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
|
433 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
434 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
|
435 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
|
436 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
437 DiffItem::Update { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
438 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
|
439 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
|
440 } => match merge(key, left_value, right_value) { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
441 MergeResult::UseLeftValue => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
442 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
|
443 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
444 MergeResult::UseRightValue => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
445 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
|
446 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
447 MergeResult::UseNewValue(new_value) => { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
448 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
|
449 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
|
450 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
451 }, |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
452 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
453 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
454 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
|
455 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
|
456 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
|
457 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
458 left |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
459 } else { |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
460 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
|
461 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
|
462 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
463 right |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
464 } |
435d9fc72646
copies-rust: extract generic map merge logic from merge_copies_dict
Simon Sapin <simon.sapin@octobus.net>
parents:
46505
diff
changeset
|
465 } |
46614
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
466 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
467 /// 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
|
468 /// `separator.join(iter)`. |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
469 /// |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
470 /// 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
|
471 /// 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
|
472 pub fn join_display( |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
473 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
|
474 separator: impl fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
475 ) -> impl fmt::Display { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
476 JoinDisplay { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
477 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
|
478 separator, |
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 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
482 struct JoinDisplay<I, S> { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
483 iter: Cell<Option<I>>, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
484 separator: S, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
485 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
486 |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
487 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
|
488 where |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
489 I: Iterator<Item = T>, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
490 T: fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
491 S: fmt::Display, |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
492 { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
493 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
|
494 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
|
495 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
|
496 first.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
497 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
498 for value in iter { |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
499 self.separator.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
500 value.fmt(f)?; |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
501 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
502 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
503 Ok(()) |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
504 } |
a069639783a0
rhg: Check .hg/requires for absence of required features
Simon Sapin <simon.sapin@octobus.net>
parents:
46601
diff
changeset
|
505 } |