Show More
@@ -0,0 +1,248 b'' | |||||
|
1 | // status.rs | |||
|
2 | // | |||
|
3 | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | |||
|
4 | // | |||
|
5 | // This software may be used and distributed according to the terms of the | |||
|
6 | // GNU General Public License version 2 or any later version. | |||
|
7 | ||||
|
8 | //! Rust implementation of dirstate.status (dirstate.py). | |||
|
9 | //! It is currently missing a lot of functionality compared to the Python one | |||
|
10 | //! and will only be triggered in narrow cases. | |||
|
11 | ||||
|
12 | use crate::utils::files::HgMetadata; | |||
|
13 | use crate::utils::hg_path::{hg_path_to_path_buf, HgPath, HgPathBuf}; | |||
|
14 | use crate::{DirstateEntry, DirstateMap, EntryState}; | |||
|
15 | use rayon::prelude::*; | |||
|
16 | use std::collections::HashMap; | |||
|
17 | use std::fs::Metadata; | |||
|
18 | use std::path::Path; | |||
|
19 | ||||
|
20 | /// Get stat data about the files explicitly specified by match. | |||
|
21 | /// TODO subrepos | |||
|
22 | fn walk_explicit( | |||
|
23 | files: &[impl AsRef<HgPath> + Sync], | |||
|
24 | dmap: &DirstateMap, | |||
|
25 | root_dir: impl AsRef<Path> + Sync, | |||
|
26 | ) -> std::io::Result<HashMap<HgPathBuf, Option<HgMetadata>>> { | |||
|
27 | let mut results = HashMap::new(); | |||
|
28 | ||||
|
29 | // A tuple of the normalized filename and the `Result` of the call to | |||
|
30 | // `symlink_metadata` for separate handling. | |||
|
31 | type WalkTuple<'a> = (&'a HgPath, std::io::Result<Metadata>); | |||
|
32 | ||||
|
33 | let stats_res: std::io::Result<Vec<WalkTuple>> = files | |||
|
34 | .par_iter() | |||
|
35 | .map(|filename| { | |||
|
36 | // TODO normalization | |||
|
37 | let normalized = filename.as_ref(); | |||
|
38 | ||||
|
39 | let target_filename = | |||
|
40 | root_dir.as_ref().join(hg_path_to_path_buf(normalized)?); | |||
|
41 | ||||
|
42 | Ok((normalized, target_filename.symlink_metadata())) | |||
|
43 | }) | |||
|
44 | .collect(); | |||
|
45 | ||||
|
46 | for res in stats_res? { | |||
|
47 | match res { | |||
|
48 | (normalized, Ok(stat)) => { | |||
|
49 | if stat.is_file() { | |||
|
50 | results.insert( | |||
|
51 | normalized.to_owned(), | |||
|
52 | Some(HgMetadata::from_metadata(stat)), | |||
|
53 | ); | |||
|
54 | } else { | |||
|
55 | if dmap.contains_key(normalized) { | |||
|
56 | results.insert(normalized.to_owned(), None); | |||
|
57 | } | |||
|
58 | } | |||
|
59 | } | |||
|
60 | (normalized, Err(_)) => { | |||
|
61 | if dmap.contains_key(normalized) { | |||
|
62 | results.insert(normalized.to_owned(), None); | |||
|
63 | } | |||
|
64 | } | |||
|
65 | }; | |||
|
66 | } | |||
|
67 | ||||
|
68 | Ok(results) | |||
|
69 | } | |||
|
70 | ||||
|
71 | // Stat all entries in the `DirstateMap` and return their new metadata. | |||
|
72 | pub fn stat_dmap_entries( | |||
|
73 | dmap: &DirstateMap, | |||
|
74 | results: &HashMap<HgPathBuf, Option<HgMetadata>>, | |||
|
75 | root_dir: impl AsRef<Path> + Sync, | |||
|
76 | ) -> std::io::Result<Vec<(HgPathBuf, Option<HgMetadata>)>> { | |||
|
77 | dmap.par_iter() | |||
|
78 | .filter_map( | |||
|
79 | // Getting file metadata is costly, so we don't do it if the | |||
|
80 | // file is already present in the results, hence `filter_map` | |||
|
81 | |(filename, _)| -> Option< | |||
|
82 | std::io::Result<(HgPathBuf, Option<HgMetadata>)> | |||
|
83 | > { | |||
|
84 | if results.contains_key(filename) { | |||
|
85 | return None; | |||
|
86 | } | |||
|
87 | let meta = match hg_path_to_path_buf(filename) { | |||
|
88 | Ok(p) => root_dir.as_ref().join(p).symlink_metadata(), | |||
|
89 | Err(e) => return Some(Err(e.into())), | |||
|
90 | }; | |||
|
91 | ||||
|
92 | Some(match meta { | |||
|
93 | Ok(ref m) | |||
|
94 | if !(m.file_type().is_file() | |||
|
95 | || m.file_type().is_symlink()) => | |||
|
96 | { | |||
|
97 | Ok((filename.to_owned(), None)) | |||
|
98 | } | |||
|
99 | Ok(m) => Ok(( | |||
|
100 | filename.to_owned(), | |||
|
101 | Some(HgMetadata::from_metadata(m)), | |||
|
102 | )), | |||
|
103 | Err(ref e) | |||
|
104 | if e.kind() == std::io::ErrorKind::NotFound | |||
|
105 | || e.raw_os_error() == Some(20) => | |||
|
106 | { | |||
|
107 | // Rust does not yet have an `ErrorKind` for | |||
|
108 | // `NotADirectory` (errno 20) | |||
|
109 | // It happens if the dirstate contains `foo/bar` and | |||
|
110 | // foo is not a directory | |||
|
111 | Ok((filename.to_owned(), None)) | |||
|
112 | } | |||
|
113 | Err(e) => Err(e), | |||
|
114 | }) | |||
|
115 | }, | |||
|
116 | ) | |||
|
117 | .collect() | |||
|
118 | } | |||
|
119 | ||||
|
120 | pub struct StatusResult { | |||
|
121 | pub modified: Vec<HgPathBuf>, | |||
|
122 | pub added: Vec<HgPathBuf>, | |||
|
123 | pub removed: Vec<HgPathBuf>, | |||
|
124 | pub deleted: Vec<HgPathBuf>, | |||
|
125 | pub clean: Vec<HgPathBuf>, | |||
|
126 | // TODO ignored | |||
|
127 | // TODO unknown | |||
|
128 | } | |||
|
129 | ||||
|
130 | fn build_response( | |||
|
131 | dmap: &DirstateMap, | |||
|
132 | list_clean: bool, | |||
|
133 | last_normal_time: i64, | |||
|
134 | check_exec: bool, | |||
|
135 | results: HashMap<HgPathBuf, Option<HgMetadata>>, | |||
|
136 | ) -> (Vec<HgPathBuf>, StatusResult) { | |||
|
137 | let mut lookup = vec![]; | |||
|
138 | let mut modified = vec![]; | |||
|
139 | let mut added = vec![]; | |||
|
140 | let mut removed = vec![]; | |||
|
141 | let mut deleted = vec![]; | |||
|
142 | let mut clean = vec![]; | |||
|
143 | ||||
|
144 | for (filename, metadata_option) in results.into_iter() { | |||
|
145 | let DirstateEntry { | |||
|
146 | state, | |||
|
147 | mode, | |||
|
148 | mtime, | |||
|
149 | size, | |||
|
150 | } = match dmap.get(&filename) { | |||
|
151 | None => { | |||
|
152 | continue; | |||
|
153 | } | |||
|
154 | Some(e) => *e, | |||
|
155 | }; | |||
|
156 | ||||
|
157 | match metadata_option { | |||
|
158 | None => { | |||
|
159 | match state { | |||
|
160 | EntryState::Normal | |||
|
161 | | EntryState::Merged | |||
|
162 | | EntryState::Added => deleted.push(filename), | |||
|
163 | EntryState::Removed => removed.push(filename), | |||
|
164 | _ => {} | |||
|
165 | }; | |||
|
166 | } | |||
|
167 | Some(HgMetadata { | |||
|
168 | st_mode, | |||
|
169 | st_size, | |||
|
170 | st_mtime, | |||
|
171 | .. | |||
|
172 | }) => { | |||
|
173 | match state { | |||
|
174 | EntryState::Normal => { | |||
|
175 | // Dates and times that are outside the 31-bit signed | |||
|
176 | // range are compared modulo 2^31. This should prevent | |||
|
177 | // it from behaving badly with very large files or | |||
|
178 | // corrupt dates while still having a high probability | |||
|
179 | // of detecting changes. (issue2608) | |||
|
180 | let range_mask = 0x7fffffff; | |||
|
181 | ||||
|
182 | let size_changed = (size != st_size as i32) | |||
|
183 | && size != (st_size as i32 & range_mask); | |||
|
184 | let mode_changed = (mode ^ st_mode as i32) & 0o100 | |||
|
185 | != 0o000 | |||
|
186 | && check_exec; | |||
|
187 | if size >= 0 | |||
|
188 | && (size_changed || mode_changed) | |||
|
189 | || size == -2 // other parent | |||
|
190 | || dmap.copy_map.contains_key(&filename) | |||
|
191 | { | |||
|
192 | modified.push(filename); | |||
|
193 | } else if mtime != st_mtime as i32 | |||
|
194 | && mtime != (st_mtime as i32 & range_mask) | |||
|
195 | { | |||
|
196 | lookup.push(filename); | |||
|
197 | } else if st_mtime == last_normal_time { | |||
|
198 | // the file may have just been marked as normal and | |||
|
199 | // it may have changed in the same second without | |||
|
200 | // changing its size. This can happen if we quickly | |||
|
201 | // do multiple commits. Force lookup, so we don't | |||
|
202 | // miss such a racy file change. | |||
|
203 | lookup.push(filename); | |||
|
204 | } else if list_clean { | |||
|
205 | clean.push(filename); | |||
|
206 | } | |||
|
207 | } | |||
|
208 | EntryState::Merged => modified.push(filename), | |||
|
209 | EntryState::Added => added.push(filename), | |||
|
210 | EntryState::Removed => removed.push(filename), | |||
|
211 | EntryState::Unknown => {} | |||
|
212 | } | |||
|
213 | } | |||
|
214 | } | |||
|
215 | } | |||
|
216 | ||||
|
217 | ( | |||
|
218 | lookup, | |||
|
219 | StatusResult { | |||
|
220 | modified, | |||
|
221 | added, | |||
|
222 | removed, | |||
|
223 | deleted, | |||
|
224 | clean, | |||
|
225 | }, | |||
|
226 | ) | |||
|
227 | } | |||
|
228 | ||||
|
229 | pub fn status( | |||
|
230 | dmap: &DirstateMap, | |||
|
231 | root_dir: impl AsRef<Path> + Sync + Copy, | |||
|
232 | files: &[impl AsRef<HgPath> + Sync], | |||
|
233 | list_clean: bool, | |||
|
234 | last_normal_time: i64, | |||
|
235 | check_exec: bool, | |||
|
236 | ) -> std::io::Result<(Vec<HgPathBuf>, StatusResult)> { | |||
|
237 | let mut results = walk_explicit(files, &dmap, root_dir)?; | |||
|
238 | ||||
|
239 | results.extend(stat_dmap_entries(&dmap, &results, root_dir)?); | |||
|
240 | ||||
|
241 | Ok(build_response( | |||
|
242 | &dmap, | |||
|
243 | list_clean, | |||
|
244 | last_normal_time, | |||
|
245 | check_exec, | |||
|
246 | results, | |||
|
247 | )) | |||
|
248 | } |
@@ -1,334 +1,440 b'' | |||||
1 | # This file is automatically @generated by Cargo. |
|
1 | # This file is automatically @generated by Cargo. | |
2 | # It is not intended for manual editing. |
|
2 | # It is not intended for manual editing. | |
3 | [[package]] |
|
3 | [[package]] | |
4 | name = "aho-corasick" |
|
4 | name = "aho-corasick" | |
5 |
version = "0. |
|
5 | version = "0.7.6" | |
6 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
6 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
7 | dependencies = [ |
|
7 | dependencies = [ | |
8 |
"memchr 2.2. |
|
8 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
|
9 | ] | |||
|
10 | ||||
|
11 | [[package]] | |||
|
12 | name = "arrayvec" | |||
|
13 | version = "0.4.12" | |||
|
14 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
15 | dependencies = [ | |||
|
16 | "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", | |||
9 | ] |
|
17 | ] | |
10 |
|
18 | |||
11 | [[package]] |
|
19 | [[package]] | |
12 | name = "autocfg" |
|
20 | name = "autocfg" | |
13 |
version = "0.1. |
|
21 | version = "0.1.6" | |
14 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
22 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
15 |
|
23 | |||
16 | [[package]] |
|
24 | [[package]] | |
17 | name = "bitflags" |
|
25 | name = "bitflags" | |
18 |
version = "1. |
|
26 | version = "1.2.1" | |
19 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
27 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
20 |
|
28 | |||
21 | [[package]] |
|
29 | [[package]] | |
22 | name = "byteorder" |
|
30 | name = "byteorder" | |
23 |
version = "1.3. |
|
31 | version = "1.3.2" | |
|
32 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
33 | ||||
|
34 | [[package]] | |||
|
35 | name = "cfg-if" | |||
|
36 | version = "0.1.10" | |||
24 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
37 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
25 |
|
38 | |||
26 | [[package]] |
|
39 | [[package]] | |
27 | name = "cloudabi" |
|
40 | name = "cloudabi" | |
28 | version = "0.0.3" |
|
41 | version = "0.0.3" | |
29 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
42 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
30 | dependencies = [ |
|
43 | dependencies = [ | |
31 |
"bitflags 1. |
|
44 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
32 | ] |
|
45 | ] | |
33 |
|
46 | |||
34 | [[package]] |
|
47 | [[package]] | |
35 | name = "cpython" |
|
48 | name = "cpython" | |
36 | version = "0.3.0" |
|
49 | version = "0.3.0" | |
37 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
50 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
38 | dependencies = [ |
|
51 | dependencies = [ | |
39 |
"libc 0.2.4 |
|
52 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
40 |
"num-traits 0.2. |
|
53 | "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | |
41 | "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
54 | "python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
42 | "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
55 | "python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
43 | ] |
|
56 | ] | |
44 |
|
57 | |||
45 | [[package]] |
|
58 | [[package]] | |
|
59 | name = "crossbeam-deque" | |||
|
60 | version = "0.7.1" | |||
|
61 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
62 | dependencies = [ | |||
|
63 | "crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
64 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
65 | ] | |||
|
66 | ||||
|
67 | [[package]] | |||
|
68 | name = "crossbeam-epoch" | |||
|
69 | version = "0.7.2" | |||
|
70 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
71 | dependencies = [ | |||
|
72 | "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
73 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
74 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
75 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
76 | "memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
77 | "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
78 | ] | |||
|
79 | ||||
|
80 | [[package]] | |||
|
81 | name = "crossbeam-queue" | |||
|
82 | version = "0.1.2" | |||
|
83 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
84 | dependencies = [ | |||
|
85 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
86 | ] | |||
|
87 | ||||
|
88 | [[package]] | |||
|
89 | name = "crossbeam-utils" | |||
|
90 | version = "0.6.6" | |||
|
91 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
92 | dependencies = [ | |||
|
93 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
94 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
95 | ] | |||
|
96 | ||||
|
97 | [[package]] | |||
|
98 | name = "either" | |||
|
99 | version = "1.5.3" | |||
|
100 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
101 | ||||
|
102 | [[package]] | |||
46 | name = "fuchsia-cprng" |
|
103 | name = "fuchsia-cprng" | |
47 |
version = "0.1. |
|
104 | version = "0.1.1" | |
48 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
105 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
49 |
|
106 | |||
50 | [[package]] |
|
107 | [[package]] | |
51 | name = "hg-core" |
|
108 | name = "hg-core" | |
52 | version = "0.1.0" |
|
109 | version = "0.1.0" | |
53 | dependencies = [ |
|
110 | dependencies = [ | |
54 |
"byteorder 1.3. |
|
111 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
55 |
"lazy_static 1. |
|
112 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
56 |
"memchr 2.2. |
|
113 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
57 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", |
|
114 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", | |
58 |
"rand_pcg 0.1. |
|
115 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
59 |
"r |
|
116 | "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
|
117 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||
60 | ] |
|
118 | ] | |
61 |
|
119 | |||
62 | [[package]] |
|
120 | [[package]] | |
63 | name = "hg-cpython" |
|
121 | name = "hg-cpython" | |
64 | version = "0.1.0" |
|
122 | version = "0.1.0" | |
65 | dependencies = [ |
|
123 | dependencies = [ | |
66 | "cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
124 | "cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
67 | "hg-core 0.1.0", |
|
125 | "hg-core 0.1.0", | |
68 |
"libc 0.2.4 |
|
126 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
69 | ] |
|
127 | ] | |
70 |
|
128 | |||
71 | [[package]] |
|
129 | [[package]] | |
72 | name = "hgdirectffi" |
|
130 | name = "hgdirectffi" | |
73 | version = "0.1.0" |
|
131 | version = "0.1.0" | |
74 | dependencies = [ |
|
132 | dependencies = [ | |
75 | "hg-core 0.1.0", |
|
133 | "hg-core 0.1.0", | |
76 |
"libc 0.2.4 |
|
134 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
77 | ] |
|
135 | ] | |
78 |
|
136 | |||
79 | [[package]] |
|
137 | [[package]] | |
80 | name = "lazy_static" |
|
138 | name = "lazy_static" | |
81 |
version = "1. |
|
139 | version = "1.4.0" | |
82 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
140 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
83 |
|
141 | |||
84 | [[package]] |
|
142 | [[package]] | |
85 | name = "libc" |
|
143 | name = "libc" | |
86 |
version = "0.2.4 |
|
144 | version = "0.2.64" | |
87 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
145 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
88 |
|
146 | |||
89 | [[package]] |
|
147 | [[package]] | |
90 | name = "memchr" |
|
148 | name = "memchr" | |
91 |
version = "2.2. |
|
149 | version = "2.2.1" | |
|
150 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
151 | ||||
|
152 | [[package]] | |||
|
153 | name = "memoffset" | |||
|
154 | version = "0.5.1" | |||
|
155 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
156 | dependencies = [ | |||
|
157 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
158 | ] | |||
|
159 | ||||
|
160 | [[package]] | |||
|
161 | name = "nodrop" | |||
|
162 | version = "0.1.14" | |||
92 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
163 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
93 |
|
164 | |||
94 | [[package]] |
|
165 | [[package]] | |
95 | name = "num-traits" |
|
166 | name = "num-traits" | |
96 |
version = "0.2. |
|
167 | version = "0.2.8" | |
97 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
168 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
|
169 | dependencies = [ | |||
|
170 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
171 | ] | |||
|
172 | ||||
|
173 | [[package]] | |||
|
174 | name = "num_cpus" | |||
|
175 | version = "1.10.1" | |||
|
176 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
177 | dependencies = [ | |||
|
178 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
179 | ] | |||
98 |
|
180 | |||
99 | [[package]] |
|
181 | [[package]] | |
100 | name = "python27-sys" |
|
182 | name = "python27-sys" | |
101 | version = "0.3.0" |
|
183 | version = "0.3.0" | |
102 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
184 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
103 | dependencies = [ |
|
185 | dependencies = [ | |
104 |
"libc 0.2.4 |
|
186 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
105 |
"regex 1. |
|
187 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
106 | ] |
|
188 | ] | |
107 |
|
189 | |||
108 | [[package]] |
|
190 | [[package]] | |
109 | name = "python3-sys" |
|
191 | name = "python3-sys" | |
110 | version = "0.3.0" |
|
192 | version = "0.3.0" | |
111 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
193 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
112 | dependencies = [ |
|
194 | dependencies = [ | |
113 |
"libc 0.2.4 |
|
195 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
114 |
"regex 1. |
|
196 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
115 | ] |
|
197 | ] | |
116 |
|
198 | |||
117 | [[package]] |
|
199 | [[package]] | |
118 | name = "rand" |
|
200 | name = "rand" | |
119 | version = "0.6.5" |
|
201 | version = "0.6.5" | |
120 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
202 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
121 | dependencies = [ |
|
203 | dependencies = [ | |
122 |
"autocfg 0.1. |
|
204 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
123 |
"libc 0.2.4 |
|
205 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
124 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
206 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
125 |
"rand_core 0.4. |
|
207 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
126 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
208 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
127 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
209 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
128 |
"rand_jitter 0.1. |
|
210 | "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | |
129 |
"rand_os 0.1. |
|
211 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", | |
130 |
"rand_pcg 0.1. |
|
212 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
131 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
213 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
132 |
"winapi 0.3. |
|
214 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | |
133 | ] |
|
215 | ] | |
134 |
|
216 | |||
135 | [[package]] |
|
217 | [[package]] | |
136 | name = "rand_chacha" |
|
218 | name = "rand_chacha" | |
137 | version = "0.1.1" |
|
219 | version = "0.1.1" | |
138 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
220 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
139 | dependencies = [ |
|
221 | dependencies = [ | |
140 |
"autocfg 0.1. |
|
222 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
141 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
223 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
142 | ] |
|
224 | ] | |
143 |
|
225 | |||
144 | [[package]] |
|
226 | [[package]] | |
145 | name = "rand_core" |
|
227 | name = "rand_core" | |
146 | version = "0.3.1" |
|
228 | version = "0.3.1" | |
147 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
229 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
148 | dependencies = [ |
|
230 | dependencies = [ | |
149 |
"rand_core 0.4. |
|
231 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
150 | ] |
|
232 | ] | |
151 |
|
233 | |||
152 | [[package]] |
|
234 | [[package]] | |
153 | name = "rand_core" |
|
235 | name = "rand_core" | |
154 |
version = "0.4. |
|
236 | version = "0.4.2" | |
155 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
237 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
156 |
|
238 | |||
157 | [[package]] |
|
239 | [[package]] | |
158 | name = "rand_hc" |
|
240 | name = "rand_hc" | |
159 | version = "0.1.0" |
|
241 | version = "0.1.0" | |
160 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
242 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
161 | dependencies = [ |
|
243 | dependencies = [ | |
162 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
244 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
163 | ] |
|
245 | ] | |
164 |
|
246 | |||
165 | [[package]] |
|
247 | [[package]] | |
166 | name = "rand_isaac" |
|
248 | name = "rand_isaac" | |
167 | version = "0.1.1" |
|
249 | version = "0.1.1" | |
168 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
250 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
169 | dependencies = [ |
|
251 | dependencies = [ | |
170 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
252 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
171 | ] |
|
253 | ] | |
172 |
|
254 | |||
173 | [[package]] |
|
255 | [[package]] | |
174 | name = "rand_jitter" |
|
256 | name = "rand_jitter" | |
175 |
version = "0.1. |
|
257 | version = "0.1.4" | |
176 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
258 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
177 | dependencies = [ |
|
259 | dependencies = [ | |
178 |
"libc 0.2.4 |
|
260 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
179 |
"rand_core 0.4. |
|
261 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
180 |
"winapi 0.3. |
|
262 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | |
181 | ] |
|
263 | ] | |
182 |
|
264 | |||
183 | [[package]] |
|
265 | [[package]] | |
184 | name = "rand_os" |
|
266 | name = "rand_os" | |
185 |
version = "0.1. |
|
267 | version = "0.1.3" | |
186 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
268 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
187 | dependencies = [ |
|
269 | dependencies = [ | |
188 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", |
|
270 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", | |
189 |
"fuchsia-cprng 0.1. |
|
271 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
190 |
"libc 0.2.4 |
|
272 | "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", | |
191 |
"rand_core 0.4. |
|
273 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
192 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
274 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
193 |
"winapi 0.3. |
|
275 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", | |
194 | ] |
|
276 | ] | |
195 |
|
277 | |||
196 | [[package]] |
|
278 | [[package]] | |
197 | name = "rand_pcg" |
|
279 | name = "rand_pcg" | |
198 |
version = "0.1. |
|
280 | version = "0.1.2" | |
199 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
281 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
200 | dependencies = [ |
|
282 | dependencies = [ | |
201 |
" |
|
283 | "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
202 |
"r |
|
284 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
203 | ] |
|
285 | ] | |
204 |
|
286 | |||
205 | [[package]] |
|
287 | [[package]] | |
206 | name = "rand_xorshift" |
|
288 | name = "rand_xorshift" | |
207 | version = "0.1.1" |
|
289 | version = "0.1.1" | |
208 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
290 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
209 | dependencies = [ |
|
291 | dependencies = [ | |
210 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
292 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
211 | ] |
|
293 | ] | |
212 |
|
294 | |||
213 | [[package]] |
|
295 | [[package]] | |
|
296 | name = "rayon" | |||
|
297 | version = "1.2.0" | |||
|
298 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
299 | dependencies = [ | |||
|
300 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
301 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
302 | "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
303 | ] | |||
|
304 | ||||
|
305 | [[package]] | |||
|
306 | name = "rayon-core" | |||
|
307 | version = "1.6.0" | |||
|
308 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
309 | dependencies = [ | |||
|
310 | "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
311 | "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
312 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
313 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
314 | "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", | |||
|
315 | ] | |||
|
316 | ||||
|
317 | [[package]] | |||
214 | name = "rdrand" |
|
318 | name = "rdrand" | |
215 | version = "0.4.0" |
|
319 | version = "0.4.0" | |
216 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
320 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
217 | dependencies = [ |
|
321 | dependencies = [ | |
218 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |
|
322 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
219 | ] |
|
323 | ] | |
220 |
|
324 | |||
221 | [[package]] |
|
325 | [[package]] | |
222 | name = "regex" |
|
326 | name = "regex" | |
223 |
version = "1. |
|
327 | version = "1.3.1" | |
224 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
328 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
225 | dependencies = [ |
|
329 | dependencies = [ | |
226 |
"aho-corasick 0. |
|
330 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
227 |
"memchr 2.2. |
|
331 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
228 |
"regex-syntax 0.6. |
|
332 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", | |
229 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", |
|
333 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
230 | "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", |
|
|||
231 | ] |
|
334 | ] | |
232 |
|
335 | |||
233 | [[package]] |
|
336 | [[package]] | |
234 | name = "regex-syntax" |
|
337 | name = "regex-syntax" | |
235 |
version = "0.6. |
|
338 | version = "0.6.12" | |
236 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
339 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
237 | dependencies = [ |
|
|||
238 | "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |
|
|||
239 | ] |
|
|||
240 |
|
340 | |||
241 | [[package]] |
|
341 | [[package]] | |
242 | name = "rustc_version" |
|
342 | name = "rustc_version" | |
243 | version = "0.2.3" |
|
343 | version = "0.2.3" | |
244 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
344 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
245 | dependencies = [ |
|
345 | dependencies = [ | |
246 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
346 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
247 | ] |
|
347 | ] | |
248 |
|
348 | |||
249 | [[package]] |
|
349 | [[package]] | |
|
350 | name = "scopeguard" | |||
|
351 | version = "1.0.0" | |||
|
352 | source = "registry+https://github.com/rust-lang/crates.io-index" | |||
|
353 | ||||
|
354 | [[package]] | |||
250 | name = "semver" |
|
355 | name = "semver" | |
251 | version = "0.9.0" |
|
356 | version = "0.9.0" | |
252 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
357 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
253 | dependencies = [ |
|
358 | dependencies = [ | |
254 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
359 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
255 | ] |
|
360 | ] | |
256 |
|
361 | |||
257 | [[package]] |
|
362 | [[package]] | |
258 | name = "semver-parser" |
|
363 | name = "semver-parser" | |
259 | version = "0.7.0" |
|
364 | version = "0.7.0" | |
260 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
365 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
261 |
|
366 | |||
262 | [[package]] |
|
367 | [[package]] | |
263 | name = "thread_local" |
|
368 | name = "thread_local" | |
264 | version = "0.3.6" |
|
369 | version = "0.3.6" | |
265 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
370 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
266 | dependencies = [ |
|
371 | dependencies = [ | |
267 |
"lazy_static 1. |
|
372 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
268 | ] |
|
373 | ] | |
269 |
|
374 | |||
270 | [[package]] |
|
375 | [[package]] | |
271 | name = "ucd-util" |
|
|||
272 | version = "0.1.3" |
|
|||
273 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
|||
274 |
|
||||
275 | [[package]] |
|
|||
276 | name = "utf8-ranges" |
|
|||
277 | version = "1.0.2" |
|
|||
278 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
|||
279 |
|
||||
280 | [[package]] |
|
|||
281 | name = "winapi" |
|
376 | name = "winapi" | |
282 |
version = "0.3. |
|
377 | version = "0.3.8" | |
283 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
378 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
284 | dependencies = [ |
|
379 | dependencies = [ | |
285 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
380 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
286 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |
|
381 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
287 | ] |
|
382 | ] | |
288 |
|
383 | |||
289 | [[package]] |
|
384 | [[package]] | |
290 | name = "winapi-i686-pc-windows-gnu" |
|
385 | name = "winapi-i686-pc-windows-gnu" | |
291 | version = "0.4.0" |
|
386 | version = "0.4.0" | |
292 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
387 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
293 |
|
388 | |||
294 | [[package]] |
|
389 | [[package]] | |
295 | name = "winapi-x86_64-pc-windows-gnu" |
|
390 | name = "winapi-x86_64-pc-windows-gnu" | |
296 | version = "0.4.0" |
|
391 | version = "0.4.0" | |
297 | source = "registry+https://github.com/rust-lang/crates.io-index" |
|
392 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
298 |
|
393 | |||
299 | [metadata] |
|
394 | [metadata] | |
300 |
"checksum aho-corasick 0. |
|
395 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" | |
301 |
"checksum a |
|
396 | "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" | |
302 |
"checksum |
|
397 | "checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" | |
303 |
"checksum b |
|
398 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" | |
|
399 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" | |||
|
400 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | |||
304 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" |
|
401 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" | |
305 | "checksum cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85532c648315aeb0829ad216a6a29aa3212cf9319bc7f6daf1404aa0bdd1485f" |
|
402 | "checksum cpython 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85532c648315aeb0829ad216a6a29aa3212cf9319bc7f6daf1404aa0bdd1485f" | |
306 | "checksum fuchsia-cprng 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "81f7f8eb465745ea9b02e2704612a9946a59fa40572086c6fd49d6ddcf30bf31" |
|
403 | "checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" | |
307 |
"checksum |
|
404 | "checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9" | |
308 | "checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74" |
|
405 | "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" | |
309 | "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" |
|
406 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" | |
310 | "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" |
|
407 | "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" | |
|
408 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" | |||
|
409 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | |||
|
410 | "checksum libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" | |||
|
411 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" | |||
|
412 | "checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f" | |||
|
413 | "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" | |||
|
414 | "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" | |||
|
415 | "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" | |||
311 | "checksum python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "372555e88a6bc8109eb641380240dc8d25a128fc48363ec9075664daadffdd5b" |
|
416 | "checksum python27-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "372555e88a6bc8109eb641380240dc8d25a128fc48363ec9075664daadffdd5b" | |
312 | "checksum python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a8ebed3f1201fda179f3960609dbbc10cd8c75e9f2afcb03788278f367d8ea" |
|
417 | "checksum python3-sys 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a8ebed3f1201fda179f3960609dbbc10cd8c75e9f2afcb03788278f367d8ea" | |
313 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" |
|
418 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" | |
314 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" |
|
419 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" | |
315 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" |
|
420 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" | |
316 |
"checksum rand_core 0.4. |
|
421 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" | |
317 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" |
|
422 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" | |
318 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" |
|
423 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" | |
319 |
"checksum rand_jitter 0.1. |
|
424 | "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" | |
320 |
"checksum rand_os 0.1. |
|
425 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" | |
321 |
"checksum rand_pcg 0.1. |
|
426 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" | |
322 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" |
|
427 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" | |
|
428 | "checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" | |||
|
429 | "checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" | |||
323 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" |
|
430 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" | |
324 |
"checksum regex 1. |
|
431 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" | |
325 |
"checksum regex-syntax 0.6. |
|
432 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" | |
326 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" |
|
433 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" | |
|
434 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" | |||
327 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" |
|
435 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" | |
328 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" |
|
436 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" | |
329 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" |
|
437 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | |
330 |
"checksum |
|
438 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" | |
331 | "checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" |
|
|||
332 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" |
|
|||
333 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |
|
439 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | |
334 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
|
440 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
@@ -1,17 +1,18 b'' | |||||
1 | [package] |
|
1 | [package] | |
2 | name = "hg-core" |
|
2 | name = "hg-core" | |
3 | version = "0.1.0" |
|
3 | version = "0.1.0" | |
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] |
|
4 | authors = ["Georges Racinet <gracinet@anybox.fr>"] | |
5 | description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)" |
|
5 | description = "Mercurial pure Rust core library, with no assumption on Python bindings (FFI)" | |
6 | edition = "2018" |
|
6 | edition = "2018" | |
7 |
|
7 | |||
8 | [lib] |
|
8 | [lib] | |
9 | name = "hg" |
|
9 | name = "hg" | |
10 |
|
10 | |||
11 | [dependencies] |
|
11 | [dependencies] | |
12 | byteorder = "1.3.1" |
|
12 | byteorder = "1.3.1" | |
13 | lazy_static = "1.3.0" |
|
13 | lazy_static = "1.3.0" | |
14 | memchr = "2.2.0" |
|
14 | memchr = "2.2.0" | |
15 | rand = "0.6.5" |
|
15 | rand = "0.6.5" | |
16 | rand_pcg = "0.1.1" |
|
16 | rand_pcg = "0.1.1" | |
17 | regex = "1.1.0" |
|
17 | regex = "1.1.0" | |
|
18 | rayon = "1.2.0" |
@@ -1,76 +1,77 b'' | |||||
1 | // dirstate module |
|
1 | // dirstate module | |
2 | // |
|
2 | // | |
3 | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> |
|
3 | // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> | |
4 | // |
|
4 | // | |
5 | // This software may be used and distributed according to the terms of the |
|
5 | // This software may be used and distributed according to the terms of the | |
6 | // GNU General Public License version 2 or any later version. |
|
6 | // GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | use crate::{utils::hg_path::HgPathBuf, DirstateParseError}; |
|
8 | use crate::{utils::hg_path::HgPathBuf, DirstateParseError}; | |
9 | use std::collections::hash_map; |
|
9 | use std::collections::hash_map; | |
10 | use std::collections::HashMap; |
|
10 | use std::collections::HashMap; | |
11 | use std::convert::TryFrom; |
|
11 | use std::convert::TryFrom; | |
12 |
|
12 | |||
13 | pub mod dirs_multiset; |
|
13 | pub mod dirs_multiset; | |
14 | pub mod dirstate_map; |
|
14 | pub mod dirstate_map; | |
15 | pub mod parsers; |
|
15 | pub mod parsers; | |
|
16 | pub mod status; | |||
16 |
|
17 | |||
17 | #[derive(Debug, PartialEq, Clone)] |
|
18 | #[derive(Debug, PartialEq, Clone)] | |
18 | pub struct DirstateParents { |
|
19 | pub struct DirstateParents { | |
19 | pub p1: [u8; 20], |
|
20 | pub p1: [u8; 20], | |
20 | pub p2: [u8; 20], |
|
21 | pub p2: [u8; 20], | |
21 | } |
|
22 | } | |
22 |
|
23 | |||
23 | /// The C implementation uses all signed types. This will be an issue |
|
24 | /// The C implementation uses all signed types. This will be an issue | |
24 | /// either when 4GB+ source files are commonplace or in 2038, whichever |
|
25 | /// either when 4GB+ source files are commonplace or in 2038, whichever | |
25 | /// comes first. |
|
26 | /// comes first. | |
26 | #[derive(Debug, PartialEq, Copy, Clone)] |
|
27 | #[derive(Debug, PartialEq, Copy, Clone)] | |
27 | pub struct DirstateEntry { |
|
28 | pub struct DirstateEntry { | |
28 | pub state: EntryState, |
|
29 | pub state: EntryState, | |
29 | pub mode: i32, |
|
30 | pub mode: i32, | |
30 | pub mtime: i32, |
|
31 | pub mtime: i32, | |
31 | pub size: i32, |
|
32 | pub size: i32, | |
32 | } |
|
33 | } | |
33 |
|
34 | |||
34 | pub type StateMap = HashMap<HgPathBuf, DirstateEntry>; |
|
35 | pub type StateMap = HashMap<HgPathBuf, DirstateEntry>; | |
35 | pub type StateMapIter<'a> = hash_map::Iter<'a, HgPathBuf, DirstateEntry>; |
|
36 | pub type StateMapIter<'a> = hash_map::Iter<'a, HgPathBuf, DirstateEntry>; | |
36 | pub type CopyMap = HashMap<HgPathBuf, HgPathBuf>; |
|
37 | pub type CopyMap = HashMap<HgPathBuf, HgPathBuf>; | |
37 | pub type CopyMapIter<'a> = hash_map::Iter<'a, HgPathBuf, HgPathBuf>; |
|
38 | pub type CopyMapIter<'a> = hash_map::Iter<'a, HgPathBuf, HgPathBuf>; | |
38 |
|
39 | |||
39 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
|
40 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | |
40 | pub enum EntryState { |
|
41 | pub enum EntryState { | |
41 | Normal, |
|
42 | Normal, | |
42 | Added, |
|
43 | Added, | |
43 | Removed, |
|
44 | Removed, | |
44 | Merged, |
|
45 | Merged, | |
45 | Unknown, |
|
46 | Unknown, | |
46 | } |
|
47 | } | |
47 |
|
48 | |||
48 | impl TryFrom<u8> for EntryState { |
|
49 | impl TryFrom<u8> for EntryState { | |
49 | type Error = DirstateParseError; |
|
50 | type Error = DirstateParseError; | |
50 |
|
51 | |||
51 | fn try_from(value: u8) -> Result<Self, Self::Error> { |
|
52 | fn try_from(value: u8) -> Result<Self, Self::Error> { | |
52 | match value { |
|
53 | match value { | |
53 | b'n' => Ok(EntryState::Normal), |
|
54 | b'n' => Ok(EntryState::Normal), | |
54 | b'a' => Ok(EntryState::Added), |
|
55 | b'a' => Ok(EntryState::Added), | |
55 | b'r' => Ok(EntryState::Removed), |
|
56 | b'r' => Ok(EntryState::Removed), | |
56 | b'm' => Ok(EntryState::Merged), |
|
57 | b'm' => Ok(EntryState::Merged), | |
57 | b'?' => Ok(EntryState::Unknown), |
|
58 | b'?' => Ok(EntryState::Unknown), | |
58 | _ => Err(DirstateParseError::CorruptedEntry(format!( |
|
59 | _ => Err(DirstateParseError::CorruptedEntry(format!( | |
59 | "Incorrect entry state {}", |
|
60 | "Incorrect entry state {}", | |
60 | value |
|
61 | value | |
61 | ))), |
|
62 | ))), | |
62 | } |
|
63 | } | |
63 | } |
|
64 | } | |
64 | } |
|
65 | } | |
65 |
|
66 | |||
66 | impl Into<u8> for EntryState { |
|
67 | impl Into<u8> for EntryState { | |
67 | fn into(self) -> u8 { |
|
68 | fn into(self) -> u8 { | |
68 | match self { |
|
69 | match self { | |
69 | EntryState::Normal => b'n', |
|
70 | EntryState::Normal => b'n', | |
70 | EntryState::Added => b'a', |
|
71 | EntryState::Added => b'a', | |
71 | EntryState::Removed => b'r', |
|
72 | EntryState::Removed => b'r', | |
72 | EntryState::Merged => b'm', |
|
73 | EntryState::Merged => b'm', | |
73 | EntryState::Unknown => b'?', |
|
74 | EntryState::Unknown => b'?', | |
74 | } |
|
75 | } | |
75 | } |
|
76 | } | |
76 | } |
|
77 | } |
@@ -1,150 +1,151 b'' | |||||
1 | // Copyright 2018 Georges Racinet <gracinet@anybox.fr> |
|
1 | // Copyright 2018 Georges Racinet <gracinet@anybox.fr> | |
2 | // |
|
2 | // | |
3 | // This software may be used and distributed according to the terms of the |
|
3 | // This software may be used and distributed according to the terms of the | |
4 | // GNU General Public License version 2 or any later version. |
|
4 | // GNU General Public License version 2 or any later version. | |
5 | mod ancestors; |
|
5 | mod ancestors; | |
6 | pub mod dagops; |
|
6 | pub mod dagops; | |
7 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; |
|
7 | pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors}; | |
8 | mod dirstate; |
|
8 | mod dirstate; | |
9 | pub mod discovery; |
|
9 | pub mod discovery; | |
10 | pub mod testing; // unconditionally built, for use from integration tests |
|
10 | pub mod testing; // unconditionally built, for use from integration tests | |
11 | pub use dirstate::{ |
|
11 | pub use dirstate::{ | |
12 | dirs_multiset::{DirsMultiset, DirsMultisetIter}, |
|
12 | dirs_multiset::{DirsMultiset, DirsMultisetIter}, | |
13 | dirstate_map::DirstateMap, |
|
13 | dirstate_map::DirstateMap, | |
14 | parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE}, |
|
14 | parsers::{pack_dirstate, parse_dirstate, PARENT_SIZE}, | |
|
15 | status::status, | |||
15 | CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState, |
|
16 | CopyMap, CopyMapIter, DirstateEntry, DirstateParents, EntryState, | |
16 | StateMap, StateMapIter, |
|
17 | StateMap, StateMapIter, | |
17 | }; |
|
18 | }; | |
18 | mod filepatterns; |
|
19 | mod filepatterns; | |
19 | pub mod utils; |
|
20 | pub mod utils; | |
20 |
|
21 | |||
21 | use crate::utils::hg_path::HgPathBuf; |
|
22 | use crate::utils::hg_path::HgPathBuf; | |
22 | pub use filepatterns::{ |
|
23 | pub use filepatterns::{ | |
23 | build_single_regex, read_pattern_file, PatternSyntax, PatternTuple, |
|
24 | build_single_regex, read_pattern_file, PatternSyntax, PatternTuple, | |
24 | }; |
|
25 | }; | |
25 |
|
26 | |||
26 | /// Mercurial revision numbers |
|
27 | /// Mercurial revision numbers | |
27 | /// |
|
28 | /// | |
28 | /// As noted in revlog.c, revision numbers are actually encoded in |
|
29 | /// As noted in revlog.c, revision numbers are actually encoded in | |
29 | /// 4 bytes, and are liberally converted to ints, whence the i32 |
|
30 | /// 4 bytes, and are liberally converted to ints, whence the i32 | |
30 | pub type Revision = i32; |
|
31 | pub type Revision = i32; | |
31 |
|
32 | |||
32 | /// Marker expressing the absence of a parent |
|
33 | /// Marker expressing the absence of a parent | |
33 | /// |
|
34 | /// | |
34 | /// Independently of the actual representation, `NULL_REVISION` is guaranteed |
|
35 | /// Independently of the actual representation, `NULL_REVISION` is guaranteed | |
35 | /// to be smaller that all existing revisions. |
|
36 | /// to be smaller that all existing revisions. | |
36 | pub const NULL_REVISION: Revision = -1; |
|
37 | pub const NULL_REVISION: Revision = -1; | |
37 |
|
38 | |||
38 | /// Same as `mercurial.node.wdirrev` |
|
39 | /// Same as `mercurial.node.wdirrev` | |
39 | /// |
|
40 | /// | |
40 | /// This is also equal to `i32::max_value()`, but it's better to spell |
|
41 | /// This is also equal to `i32::max_value()`, but it's better to spell | |
41 | /// it out explicitely, same as in `mercurial.node` |
|
42 | /// it out explicitely, same as in `mercurial.node` | |
42 | pub const WORKING_DIRECTORY_REVISION: Revision = 0x7fffffff; |
|
43 | pub const WORKING_DIRECTORY_REVISION: Revision = 0x7fffffff; | |
43 |
|
44 | |||
44 | /// The simplest expression of what we need of Mercurial DAGs. |
|
45 | /// The simplest expression of what we need of Mercurial DAGs. | |
45 | pub trait Graph { |
|
46 | pub trait Graph { | |
46 | /// Return the two parents of the given `Revision`. |
|
47 | /// Return the two parents of the given `Revision`. | |
47 | /// |
|
48 | /// | |
48 | /// Each of the parents can be independently `NULL_REVISION` |
|
49 | /// Each of the parents can be independently `NULL_REVISION` | |
49 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>; |
|
50 | fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>; | |
50 | } |
|
51 | } | |
51 |
|
52 | |||
52 | pub type LineNumber = usize; |
|
53 | pub type LineNumber = usize; | |
53 |
|
54 | |||
54 | #[derive(Clone, Debug, PartialEq)] |
|
55 | #[derive(Clone, Debug, PartialEq)] | |
55 | pub enum GraphError { |
|
56 | pub enum GraphError { | |
56 | ParentOutOfRange(Revision), |
|
57 | ParentOutOfRange(Revision), | |
57 | WorkingDirectoryUnsupported, |
|
58 | WorkingDirectoryUnsupported, | |
58 | } |
|
59 | } | |
59 |
|
60 | |||
60 | #[derive(Clone, Debug, PartialEq)] |
|
61 | #[derive(Clone, Debug, PartialEq)] | |
61 | pub enum DirstateParseError { |
|
62 | pub enum DirstateParseError { | |
62 | TooLittleData, |
|
63 | TooLittleData, | |
63 | Overflow, |
|
64 | Overflow, | |
64 | CorruptedEntry(String), |
|
65 | CorruptedEntry(String), | |
65 | Damaged, |
|
66 | Damaged, | |
66 | } |
|
67 | } | |
67 |
|
68 | |||
68 | impl From<std::io::Error> for DirstateParseError { |
|
69 | impl From<std::io::Error> for DirstateParseError { | |
69 | fn from(e: std::io::Error) -> Self { |
|
70 | fn from(e: std::io::Error) -> Self { | |
70 | DirstateParseError::CorruptedEntry(e.to_string()) |
|
71 | DirstateParseError::CorruptedEntry(e.to_string()) | |
71 | } |
|
72 | } | |
72 | } |
|
73 | } | |
73 |
|
74 | |||
74 | impl ToString for DirstateParseError { |
|
75 | impl ToString for DirstateParseError { | |
75 | fn to_string(&self) -> String { |
|
76 | fn to_string(&self) -> String { | |
76 | use crate::DirstateParseError::*; |
|
77 | use crate::DirstateParseError::*; | |
77 | match self { |
|
78 | match self { | |
78 | TooLittleData => "Too little data for dirstate.".to_string(), |
|
79 | TooLittleData => "Too little data for dirstate.".to_string(), | |
79 | Overflow => "Overflow in dirstate.".to_string(), |
|
80 | Overflow => "Overflow in dirstate.".to_string(), | |
80 | CorruptedEntry(e) => format!("Corrupted entry: {:?}.", e), |
|
81 | CorruptedEntry(e) => format!("Corrupted entry: {:?}.", e), | |
81 | Damaged => "Dirstate appears to be damaged.".to_string(), |
|
82 | Damaged => "Dirstate appears to be damaged.".to_string(), | |
82 | } |
|
83 | } | |
83 | } |
|
84 | } | |
84 | } |
|
85 | } | |
85 |
|
86 | |||
86 | #[derive(Debug, PartialEq)] |
|
87 | #[derive(Debug, PartialEq)] | |
87 | pub enum DirstatePackError { |
|
88 | pub enum DirstatePackError { | |
88 | CorruptedEntry(String), |
|
89 | CorruptedEntry(String), | |
89 | CorruptedParent, |
|
90 | CorruptedParent, | |
90 | BadSize(usize, usize), |
|
91 | BadSize(usize, usize), | |
91 | } |
|
92 | } | |
92 |
|
93 | |||
93 | impl From<std::io::Error> for DirstatePackError { |
|
94 | impl From<std::io::Error> for DirstatePackError { | |
94 | fn from(e: std::io::Error) -> Self { |
|
95 | fn from(e: std::io::Error) -> Self { | |
95 | DirstatePackError::CorruptedEntry(e.to_string()) |
|
96 | DirstatePackError::CorruptedEntry(e.to_string()) | |
96 | } |
|
97 | } | |
97 | } |
|
98 | } | |
98 | #[derive(Debug, PartialEq)] |
|
99 | #[derive(Debug, PartialEq)] | |
99 | pub enum DirstateMapError { |
|
100 | pub enum DirstateMapError { | |
100 | PathNotFound(HgPathBuf), |
|
101 | PathNotFound(HgPathBuf), | |
101 | EmptyPath, |
|
102 | EmptyPath, | |
102 | } |
|
103 | } | |
103 |
|
104 | |||
104 | pub enum DirstateError { |
|
105 | pub enum DirstateError { | |
105 | Parse(DirstateParseError), |
|
106 | Parse(DirstateParseError), | |
106 | Pack(DirstatePackError), |
|
107 | Pack(DirstatePackError), | |
107 | Map(DirstateMapError), |
|
108 | Map(DirstateMapError), | |
108 | IO(std::io::Error), |
|
109 | IO(std::io::Error), | |
109 | } |
|
110 | } | |
110 |
|
111 | |||
111 | impl From<DirstateParseError> for DirstateError { |
|
112 | impl From<DirstateParseError> for DirstateError { | |
112 | fn from(e: DirstateParseError) -> Self { |
|
113 | fn from(e: DirstateParseError) -> Self { | |
113 | DirstateError::Parse(e) |
|
114 | DirstateError::Parse(e) | |
114 | } |
|
115 | } | |
115 | } |
|
116 | } | |
116 |
|
117 | |||
117 | impl From<DirstatePackError> for DirstateError { |
|
118 | impl From<DirstatePackError> for DirstateError { | |
118 | fn from(e: DirstatePackError) -> Self { |
|
119 | fn from(e: DirstatePackError) -> Self { | |
119 | DirstateError::Pack(e) |
|
120 | DirstateError::Pack(e) | |
120 | } |
|
121 | } | |
121 | } |
|
122 | } | |
122 |
|
123 | |||
123 | #[derive(Debug)] |
|
124 | #[derive(Debug)] | |
124 | pub enum PatternError { |
|
125 | pub enum PatternError { | |
125 | UnsupportedSyntax(String), |
|
126 | UnsupportedSyntax(String), | |
126 | } |
|
127 | } | |
127 |
|
128 | |||
128 | #[derive(Debug)] |
|
129 | #[derive(Debug)] | |
129 | pub enum PatternFileError { |
|
130 | pub enum PatternFileError { | |
130 | IO(std::io::Error), |
|
131 | IO(std::io::Error), | |
131 | Pattern(PatternError, LineNumber), |
|
132 | Pattern(PatternError, LineNumber), | |
132 | } |
|
133 | } | |
133 |
|
134 | |||
134 | impl From<std::io::Error> for PatternFileError { |
|
135 | impl From<std::io::Error> for PatternFileError { | |
135 | fn from(e: std::io::Error) -> Self { |
|
136 | fn from(e: std::io::Error) -> Self { | |
136 | PatternFileError::IO(e) |
|
137 | PatternFileError::IO(e) | |
137 | } |
|
138 | } | |
138 | } |
|
139 | } | |
139 |
|
140 | |||
140 | impl From<DirstateMapError> for DirstateError { |
|
141 | impl From<DirstateMapError> for DirstateError { | |
141 | fn from(e: DirstateMapError) -> Self { |
|
142 | fn from(e: DirstateMapError) -> Self { | |
142 | DirstateError::Map(e) |
|
143 | DirstateError::Map(e) | |
143 | } |
|
144 | } | |
144 | } |
|
145 | } | |
145 |
|
146 | |||
146 | impl From<std::io::Error> for DirstateError { |
|
147 | impl From<std::io::Error> for DirstateError { | |
147 | fn from(e: std::io::Error) -> Self { |
|
148 | fn from(e: std::io::Error) -> Self { | |
148 | DirstateError::IO(e) |
|
149 | DirstateError::IO(e) | |
149 | } |
|
150 | } | |
150 | } |
|
151 | } |
@@ -1,101 +1,128 b'' | |||||
1 | // files.rs |
|
1 | // files.rs | |
2 | // |
|
2 | // | |
3 | // Copyright 2019 |
|
3 | // Copyright 2019 | |
4 | // Raphaël Gomès <rgomes@octobus.net>, |
|
4 | // Raphaël Gomès <rgomes@octobus.net>, | |
5 | // Yuya Nishihara <yuya@tcha.org> |
|
5 | // Yuya Nishihara <yuya@tcha.org> | |
6 | // |
|
6 | // | |
7 | // This software may be used and distributed according to the terms of the |
|
7 | // This software may be used and distributed according to the terms of the | |
8 | // GNU General Public License version 2 or any later version. |
|
8 | // GNU General Public License version 2 or any later version. | |
9 |
|
9 | |||
10 | //! Functions for fiddling with files. |
|
10 | //! Functions for fiddling with files. | |
11 |
|
11 | |||
12 | use crate::utils::hg_path::{HgPath, HgPathBuf}; |
|
12 | use crate::utils::hg_path::{HgPath, HgPathBuf}; | |
13 | use std::iter::FusedIterator; |
|
13 | use std::iter::FusedIterator; | |
14 |
|
14 | |||
|
15 | use std::fs::Metadata; | |||
15 | use std::path::Path; |
|
16 | use std::path::Path; | |
16 |
|
17 | |||
17 | pub fn get_path_from_bytes(bytes: &[u8]) -> &Path { |
|
18 | pub fn get_path_from_bytes(bytes: &[u8]) -> &Path { | |
18 | let os_str; |
|
19 | let os_str; | |
19 | #[cfg(unix)] |
|
20 | #[cfg(unix)] | |
20 | { |
|
21 | { | |
21 | use std::os::unix::ffi::OsStrExt; |
|
22 | use std::os::unix::ffi::OsStrExt; | |
22 | os_str = std::ffi::OsStr::from_bytes(bytes); |
|
23 | os_str = std::ffi::OsStr::from_bytes(bytes); | |
23 | } |
|
24 | } | |
24 | // TODO Handle other platforms |
|
25 | // TODO Handle other platforms | |
25 | // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). |
|
26 | // TODO: convert from WTF8 to Windows MBCS (ANSI encoding). | |
26 | // Perhaps, the return type would have to be Result<PathBuf>. |
|
27 | // Perhaps, the return type would have to be Result<PathBuf>. | |
27 |
|
28 | |||
28 | Path::new(os_str) |
|
29 | Path::new(os_str) | |
29 | } |
|
30 | } | |
30 |
|
31 | |||
31 | /// An iterator over repository path yielding itself and its ancestors. |
|
32 | /// An iterator over repository path yielding itself and its ancestors. | |
32 | #[derive(Copy, Clone, Debug)] |
|
33 | #[derive(Copy, Clone, Debug)] | |
33 | pub struct Ancestors<'a> { |
|
34 | pub struct Ancestors<'a> { | |
34 | next: Option<&'a HgPath>, |
|
35 | next: Option<&'a HgPath>, | |
35 | } |
|
36 | } | |
36 |
|
37 | |||
37 | impl<'a> Iterator for Ancestors<'a> { |
|
38 | impl<'a> Iterator for Ancestors<'a> { | |
38 | type Item = &'a HgPath; |
|
39 | type Item = &'a HgPath; | |
39 |
|
40 | |||
40 | fn next(&mut self) -> Option<Self::Item> { |
|
41 | fn next(&mut self) -> Option<Self::Item> { | |
41 | let next = self.next; |
|
42 | let next = self.next; | |
42 | self.next = match self.next { |
|
43 | self.next = match self.next { | |
43 | Some(s) if s.is_empty() => None, |
|
44 | Some(s) if s.is_empty() => None, | |
44 | Some(s) => { |
|
45 | Some(s) => { | |
45 | let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0); |
|
46 | let p = s.bytes().rposition(|c| *c == b'/').unwrap_or(0); | |
46 | Some(HgPath::new(&s.as_bytes()[..p])) |
|
47 | Some(HgPath::new(&s.as_bytes()[..p])) | |
47 | } |
|
48 | } | |
48 | None => None, |
|
49 | None => None, | |
49 | }; |
|
50 | }; | |
50 | next |
|
51 | next | |
51 | } |
|
52 | } | |
52 | } |
|
53 | } | |
53 |
|
54 | |||
54 | impl<'a> FusedIterator for Ancestors<'a> {} |
|
55 | impl<'a> FusedIterator for Ancestors<'a> {} | |
55 |
|
56 | |||
56 | /// Returns an iterator yielding ancestor directories of the given repository |
|
57 | /// Returns an iterator yielding ancestor directories of the given repository | |
57 | /// path. |
|
58 | /// path. | |
58 | /// |
|
59 | /// | |
59 | /// The path is separated by '/', and must not start with '/'. |
|
60 | /// The path is separated by '/', and must not start with '/'. | |
60 | /// |
|
61 | /// | |
61 | /// The path itself isn't included unless it is b"" (meaning the root |
|
62 | /// The path itself isn't included unless it is b"" (meaning the root | |
62 | /// directory.) |
|
63 | /// directory.) | |
63 | pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> { |
|
64 | pub fn find_dirs<'a>(path: &'a HgPath) -> Ancestors<'a> { | |
64 | let mut dirs = Ancestors { next: Some(path) }; |
|
65 | let mut dirs = Ancestors { next: Some(path) }; | |
65 | if !path.is_empty() { |
|
66 | if !path.is_empty() { | |
66 | dirs.next(); // skip itself |
|
67 | dirs.next(); // skip itself | |
67 | } |
|
68 | } | |
68 | dirs |
|
69 | dirs | |
69 | } |
|
70 | } | |
70 |
|
71 | |||
71 | /// TODO more than ASCII? |
|
72 | /// TODO more than ASCII? | |
72 | pub fn normalize_case(path: &HgPath) -> HgPathBuf { |
|
73 | pub fn normalize_case(path: &HgPath) -> HgPathBuf { | |
73 | #[cfg(windows)] // NTFS compares via upper() |
|
74 | #[cfg(windows)] // NTFS compares via upper() | |
74 | return path.to_ascii_uppercase(); |
|
75 | return path.to_ascii_uppercase(); | |
75 | #[cfg(unix)] |
|
76 | #[cfg(unix)] | |
76 | path.to_ascii_lowercase() |
|
77 | path.to_ascii_lowercase() | |
77 | } |
|
78 | } | |
78 |
|
79 | |||
|
80 | #[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)] | |||
|
81 | pub struct HgMetadata { | |||
|
82 | pub st_dev: u64, | |||
|
83 | pub st_mode: u32, | |||
|
84 | pub st_nlink: u64, | |||
|
85 | pub st_size: u64, | |||
|
86 | pub st_mtime: i64, | |||
|
87 | pub st_ctime: i64, | |||
|
88 | } | |||
|
89 | ||||
|
90 | // TODO support other plaforms | |||
|
91 | #[cfg(unix)] | |||
|
92 | impl HgMetadata { | |||
|
93 | pub fn from_metadata(metadata: Metadata) -> Self { | |||
|
94 | use std::os::unix::fs::MetadataExt; | |||
|
95 | Self { | |||
|
96 | st_dev: metadata.dev(), | |||
|
97 | st_mode: metadata.mode(), | |||
|
98 | st_nlink: metadata.nlink(), | |||
|
99 | st_size: metadata.size(), | |||
|
100 | st_mtime: metadata.mtime(), | |||
|
101 | st_ctime: metadata.ctime(), | |||
|
102 | } | |||
|
103 | } | |||
|
104 | } | |||
|
105 | ||||
79 | #[cfg(test)] |
|
106 | #[cfg(test)] | |
80 | mod tests { |
|
107 | mod tests { | |
81 | use super::*; |
|
108 | use super::*; | |
82 |
|
109 | |||
83 | #[test] |
|
110 | #[test] | |
84 | fn find_dirs_some() { |
|
111 | fn find_dirs_some() { | |
85 | let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz")); |
|
112 | let mut dirs = super::find_dirs(HgPath::new(b"foo/bar/baz")); | |
86 | assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar"))); |
|
113 | assert_eq!(dirs.next(), Some(HgPath::new(b"foo/bar"))); | |
87 | assert_eq!(dirs.next(), Some(HgPath::new(b"foo"))); |
|
114 | assert_eq!(dirs.next(), Some(HgPath::new(b"foo"))); | |
88 | assert_eq!(dirs.next(), Some(HgPath::new(b""))); |
|
115 | assert_eq!(dirs.next(), Some(HgPath::new(b""))); | |
89 | assert_eq!(dirs.next(), None); |
|
116 | assert_eq!(dirs.next(), None); | |
90 | assert_eq!(dirs.next(), None); |
|
117 | assert_eq!(dirs.next(), None); | |
91 | } |
|
118 | } | |
92 |
|
119 | |||
93 | #[test] |
|
120 | #[test] | |
94 | fn find_dirs_empty() { |
|
121 | fn find_dirs_empty() { | |
95 | // looks weird, but mercurial.util.finddirs(b"") yields b"" |
|
122 | // looks weird, but mercurial.util.finddirs(b"") yields b"" | |
96 | let mut dirs = super::find_dirs(HgPath::new(b"")); |
|
123 | let mut dirs = super::find_dirs(HgPath::new(b"")); | |
97 | assert_eq!(dirs.next(), Some(HgPath::new(b""))); |
|
124 | assert_eq!(dirs.next(), Some(HgPath::new(b""))); | |
98 | assert_eq!(dirs.next(), None); |
|
125 | assert_eq!(dirs.next(), None); | |
99 | assert_eq!(dirs.next(), None); |
|
126 | assert_eq!(dirs.next(), None); | |
100 | } |
|
127 | } | |
101 | } |
|
128 | } |
General Comments 0
You need to be logged in to leave comments.
Login now