##// END OF EJS Templates
rust: Make OwningDirstateMap generic and move it into hg-core...
Simon Sapin -
r48766:4afd6cc4 default
parent child Browse files
Show More
@@ -1,1071 +1,1081 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 version = 3
4
3 [[package]]
5 [[package]]
4 name = "adler"
6 name = "adler"
5 version = "0.2.3"
7 version = "0.2.3"
6 source = "registry+https://github.com/rust-lang/crates.io-index"
8 source = "registry+https://github.com/rust-lang/crates.io-index"
7 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
9 checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
8
10
9 [[package]]
11 [[package]]
10 name = "aho-corasick"
12 name = "aho-corasick"
11 version = "0.7.15"
13 version = "0.7.15"
12 source = "registry+https://github.com/rust-lang/crates.io-index"
14 source = "registry+https://github.com/rust-lang/crates.io-index"
13 checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
15 checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
14 dependencies = [
16 dependencies = [
15 "memchr",
17 "memchr",
16 ]
18 ]
17
19
18 [[package]]
20 [[package]]
19 name = "ansi_term"
21 name = "ansi_term"
20 version = "0.11.0"
22 version = "0.11.0"
21 source = "registry+https://github.com/rust-lang/crates.io-index"
23 source = "registry+https://github.com/rust-lang/crates.io-index"
22 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
24 checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
23 dependencies = [
25 dependencies = [
24 "winapi",
26 "winapi",
25 ]
27 ]
26
28
27 [[package]]
29 [[package]]
28 name = "atty"
30 name = "atty"
29 version = "0.2.14"
31 version = "0.2.14"
30 source = "registry+https://github.com/rust-lang/crates.io-index"
32 source = "registry+https://github.com/rust-lang/crates.io-index"
31 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
33 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
32 dependencies = [
34 dependencies = [
33 "hermit-abi",
35 "hermit-abi",
34 "libc",
36 "libc",
35 "winapi",
37 "winapi",
36 ]
38 ]
37
39
38 [[package]]
40 [[package]]
39 name = "autocfg"
41 name = "autocfg"
40 version = "1.0.1"
42 version = "1.0.1"
41 source = "registry+https://github.com/rust-lang/crates.io-index"
43 source = "registry+https://github.com/rust-lang/crates.io-index"
42 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
44 checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
43
45
44 [[package]]
46 [[package]]
45 name = "bitflags"
47 name = "bitflags"
46 version = "1.2.1"
48 version = "1.2.1"
47 source = "registry+https://github.com/rust-lang/crates.io-index"
49 source = "registry+https://github.com/rust-lang/crates.io-index"
48 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
50 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
49
51
50 [[package]]
52 [[package]]
51 name = "bitmaps"
53 name = "bitmaps"
52 version = "2.1.0"
54 version = "2.1.0"
53 source = "registry+https://github.com/rust-lang/crates.io-index"
55 source = "registry+https://github.com/rust-lang/crates.io-index"
54 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
56 checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
55 dependencies = [
57 dependencies = [
56 "typenum",
58 "typenum",
57 ]
59 ]
58
60
59 [[package]]
61 [[package]]
60 name = "block-buffer"
62 name = "block-buffer"
61 version = "0.9.0"
63 version = "0.9.0"
62 source = "registry+https://github.com/rust-lang/crates.io-index"
64 source = "registry+https://github.com/rust-lang/crates.io-index"
63 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
65 checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
64 dependencies = [
66 dependencies = [
65 "generic-array",
67 "generic-array",
66 ]
68 ]
67
69
68 [[package]]
70 [[package]]
69 name = "byteorder"
71 name = "byteorder"
70 version = "1.3.4"
72 version = "1.3.4"
71 source = "registry+https://github.com/rust-lang/crates.io-index"
73 source = "registry+https://github.com/rust-lang/crates.io-index"
72 checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
74 checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
73
75
74 [[package]]
76 [[package]]
75 name = "bytes-cast"
77 name = "bytes-cast"
76 version = "0.2.0"
78 version = "0.2.0"
77 source = "registry+https://github.com/rust-lang/crates.io-index"
79 source = "registry+https://github.com/rust-lang/crates.io-index"
78 checksum = "0d434f9a4ecbe987e7ccfda7274b6f82ea52c9b63742565a65cb5e8ba0f2c452"
80 checksum = "0d434f9a4ecbe987e7ccfda7274b6f82ea52c9b63742565a65cb5e8ba0f2c452"
79 dependencies = [
81 dependencies = [
80 "bytes-cast-derive",
82 "bytes-cast-derive",
81 ]
83 ]
82
84
83 [[package]]
85 [[package]]
84 name = "bytes-cast-derive"
86 name = "bytes-cast-derive"
85 version = "0.1.0"
87 version = "0.1.0"
86 source = "registry+https://github.com/rust-lang/crates.io-index"
88 source = "registry+https://github.com/rust-lang/crates.io-index"
87 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
89 checksum = "cb936af9de38476664d6b58e529aff30d482e4ce1c5e150293d00730b0d81fdb"
88 dependencies = [
90 dependencies = [
89 "proc-macro2",
91 "proc-macro2",
90 "quote",
92 "quote",
91 "syn",
93 "syn",
92 ]
94 ]
93
95
94 [[package]]
96 [[package]]
95 name = "cc"
97 name = "cc"
96 version = "1.0.66"
98 version = "1.0.66"
97 source = "registry+https://github.com/rust-lang/crates.io-index"
99 source = "registry+https://github.com/rust-lang/crates.io-index"
98 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
100 checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
99 dependencies = [
101 dependencies = [
100 "jobserver",
102 "jobserver",
101 ]
103 ]
102
104
103 [[package]]
105 [[package]]
104 name = "cfg-if"
106 name = "cfg-if"
105 version = "0.1.10"
107 version = "0.1.10"
106 source = "registry+https://github.com/rust-lang/crates.io-index"
108 source = "registry+https://github.com/rust-lang/crates.io-index"
107 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
109 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
108
110
109 [[package]]
111 [[package]]
110 name = "cfg-if"
112 name = "cfg-if"
111 version = "1.0.0"
113 version = "1.0.0"
112 source = "registry+https://github.com/rust-lang/crates.io-index"
114 source = "registry+https://github.com/rust-lang/crates.io-index"
113 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
115 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
114
116
115 [[package]]
117 [[package]]
116 name = "chrono"
118 name = "chrono"
117 version = "0.4.19"
119 version = "0.4.19"
118 source = "registry+https://github.com/rust-lang/crates.io-index"
120 source = "registry+https://github.com/rust-lang/crates.io-index"
119 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
121 checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
120 dependencies = [
122 dependencies = [
121 "libc",
123 "libc",
122 "num-integer",
124 "num-integer",
123 "num-traits",
125 "num-traits",
124 "time",
126 "time",
125 "winapi",
127 "winapi",
126 ]
128 ]
127
129
128 [[package]]
130 [[package]]
129 name = "clap"
131 name = "clap"
130 version = "2.33.3"
132 version = "2.33.3"
131 source = "registry+https://github.com/rust-lang/crates.io-index"
133 source = "registry+https://github.com/rust-lang/crates.io-index"
132 checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
134 checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
133 dependencies = [
135 dependencies = [
134 "ansi_term",
136 "ansi_term",
135 "atty",
137 "atty",
136 "bitflags",
138 "bitflags",
137 "strsim",
139 "strsim",
138 "textwrap",
140 "textwrap",
139 "unicode-width",
141 "unicode-width",
140 "vec_map",
142 "vec_map",
141 ]
143 ]
142
144
143 [[package]]
145 [[package]]
144 name = "const_fn"
146 name = "const_fn"
145 version = "0.4.4"
147 version = "0.4.4"
146 source = "registry+https://github.com/rust-lang/crates.io-index"
148 source = "registry+https://github.com/rust-lang/crates.io-index"
147 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
149 checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
148
150
149 [[package]]
151 [[package]]
150 name = "cpufeatures"
152 name = "cpufeatures"
151 version = "0.1.4"
153 version = "0.1.4"
152 source = "registry+https://github.com/rust-lang/crates.io-index"
154 source = "registry+https://github.com/rust-lang/crates.io-index"
153 checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
155 checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8"
154 dependencies = [
156 dependencies = [
155 "libc",
157 "libc",
156 ]
158 ]
157
159
158 [[package]]
160 [[package]]
159 name = "cpython"
161 name = "cpython"
160 version = "0.6.0"
162 version = "0.6.0"
161 source = "registry+https://github.com/rust-lang/crates.io-index"
163 source = "registry+https://github.com/rust-lang/crates.io-index"
162 checksum = "8094679a4e9bfc8035572162624bc800eda35b5f9eff2537b9cd9aacc3d9782e"
164 checksum = "8094679a4e9bfc8035572162624bc800eda35b5f9eff2537b9cd9aacc3d9782e"
163 dependencies = [
165 dependencies = [
164 "libc",
166 "libc",
165 "num-traits",
167 "num-traits",
166 "paste",
168 "paste",
167 "python27-sys",
169 "python27-sys",
168 "python3-sys",
170 "python3-sys",
169 ]
171 ]
170
172
171 [[package]]
173 [[package]]
172 name = "crc32fast"
174 name = "crc32fast"
173 version = "1.2.1"
175 version = "1.2.1"
174 source = "registry+https://github.com/rust-lang/crates.io-index"
176 source = "registry+https://github.com/rust-lang/crates.io-index"
175 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
177 checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
176 dependencies = [
178 dependencies = [
177 "cfg-if 1.0.0",
179 "cfg-if 1.0.0",
178 ]
180 ]
179
181
180 [[package]]
182 [[package]]
181 name = "crossbeam-channel"
183 name = "crossbeam-channel"
182 version = "0.4.4"
184 version = "0.4.4"
183 source = "registry+https://github.com/rust-lang/crates.io-index"
185 source = "registry+https://github.com/rust-lang/crates.io-index"
184 checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
186 checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
185 dependencies = [
187 dependencies = [
186 "crossbeam-utils 0.7.2",
188 "crossbeam-utils 0.7.2",
187 "maybe-uninit",
189 "maybe-uninit",
188 ]
190 ]
189
191
190 [[package]]
192 [[package]]
191 name = "crossbeam-channel"
193 name = "crossbeam-channel"
192 version = "0.5.0"
194 version = "0.5.0"
193 source = "registry+https://github.com/rust-lang/crates.io-index"
195 source = "registry+https://github.com/rust-lang/crates.io-index"
194 checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
196 checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
195 dependencies = [
197 dependencies = [
196 "cfg-if 1.0.0",
198 "cfg-if 1.0.0",
197 "crossbeam-utils 0.8.1",
199 "crossbeam-utils 0.8.1",
198 ]
200 ]
199
201
200 [[package]]
202 [[package]]
201 name = "crossbeam-deque"
203 name = "crossbeam-deque"
202 version = "0.8.0"
204 version = "0.8.0"
203 source = "registry+https://github.com/rust-lang/crates.io-index"
205 source = "registry+https://github.com/rust-lang/crates.io-index"
204 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
206 checksum = "94af6efb46fef72616855b036a624cf27ba656ffc9be1b9a3c931cfc7749a9a9"
205 dependencies = [
207 dependencies = [
206 "cfg-if 1.0.0",
208 "cfg-if 1.0.0",
207 "crossbeam-epoch",
209 "crossbeam-epoch",
208 "crossbeam-utils 0.8.1",
210 "crossbeam-utils 0.8.1",
209 ]
211 ]
210
212
211 [[package]]
213 [[package]]
212 name = "crossbeam-epoch"
214 name = "crossbeam-epoch"
213 version = "0.9.1"
215 version = "0.9.1"
214 source = "registry+https://github.com/rust-lang/crates.io-index"
216 source = "registry+https://github.com/rust-lang/crates.io-index"
215 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
217 checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
216 dependencies = [
218 dependencies = [
217 "cfg-if 1.0.0",
219 "cfg-if 1.0.0",
218 "const_fn",
220 "const_fn",
219 "crossbeam-utils 0.8.1",
221 "crossbeam-utils 0.8.1",
220 "lazy_static",
222 "lazy_static",
221 "memoffset",
223 "memoffset",
222 "scopeguard",
224 "scopeguard",
223 ]
225 ]
224
226
225 [[package]]
227 [[package]]
226 name = "crossbeam-utils"
228 name = "crossbeam-utils"
227 version = "0.7.2"
229 version = "0.7.2"
228 source = "registry+https://github.com/rust-lang/crates.io-index"
230 source = "registry+https://github.com/rust-lang/crates.io-index"
229 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
231 checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
230 dependencies = [
232 dependencies = [
231 "autocfg",
233 "autocfg",
232 "cfg-if 0.1.10",
234 "cfg-if 0.1.10",
233 "lazy_static",
235 "lazy_static",
234 ]
236 ]
235
237
236 [[package]]
238 [[package]]
237 name = "crossbeam-utils"
239 name = "crossbeam-utils"
238 version = "0.8.1"
240 version = "0.8.1"
239 source = "registry+https://github.com/rust-lang/crates.io-index"
241 source = "registry+https://github.com/rust-lang/crates.io-index"
240 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
242 checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
241 dependencies = [
243 dependencies = [
242 "autocfg",
244 "autocfg",
243 "cfg-if 1.0.0",
245 "cfg-if 1.0.0",
244 "lazy_static",
246 "lazy_static",
245 ]
247 ]
246
248
247 [[package]]
249 [[package]]
248 name = "ctor"
250 name = "ctor"
249 version = "0.1.16"
251 version = "0.1.16"
250 source = "registry+https://github.com/rust-lang/crates.io-index"
252 source = "registry+https://github.com/rust-lang/crates.io-index"
251 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
253 checksum = "7fbaabec2c953050352311293be5c6aba8e141ba19d6811862b232d6fd020484"
252 dependencies = [
254 dependencies = [
253 "quote",
255 "quote",
254 "syn",
256 "syn",
255 ]
257 ]
256
258
257 [[package]]
259 [[package]]
258 name = "derive_more"
260 name = "derive_more"
259 version = "0.99.11"
261 version = "0.99.11"
260 source = "registry+https://github.com/rust-lang/crates.io-index"
262 source = "registry+https://github.com/rust-lang/crates.io-index"
261 checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
263 checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
262 dependencies = [
264 dependencies = [
263 "proc-macro2",
265 "proc-macro2",
264 "quote",
266 "quote",
265 "syn",
267 "syn",
266 ]
268 ]
267
269
268 [[package]]
270 [[package]]
269 name = "difference"
271 name = "difference"
270 version = "2.0.0"
272 version = "2.0.0"
271 source = "registry+https://github.com/rust-lang/crates.io-index"
273 source = "registry+https://github.com/rust-lang/crates.io-index"
272 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
274 checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
273
275
274 [[package]]
276 [[package]]
275 name = "digest"
277 name = "digest"
276 version = "0.9.0"
278 version = "0.9.0"
277 source = "registry+https://github.com/rust-lang/crates.io-index"
279 source = "registry+https://github.com/rust-lang/crates.io-index"
278 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
280 checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
279 dependencies = [
281 dependencies = [
280 "generic-array",
282 "generic-array",
281 ]
283 ]
282
284
283 [[package]]
285 [[package]]
284 name = "either"
286 name = "either"
285 version = "1.6.1"
287 version = "1.6.1"
286 source = "registry+https://github.com/rust-lang/crates.io-index"
288 source = "registry+https://github.com/rust-lang/crates.io-index"
287 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
289 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
288
290
289 [[package]]
291 [[package]]
290 name = "env_logger"
292 name = "env_logger"
291 version = "0.7.1"
293 version = "0.7.1"
292 source = "registry+https://github.com/rust-lang/crates.io-index"
294 source = "registry+https://github.com/rust-lang/crates.io-index"
293 checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
295 checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
294 dependencies = [
296 dependencies = [
295 "atty",
297 "atty",
296 "humantime",
298 "humantime",
297 "log",
299 "log",
298 "regex",
300 "regex",
299 "termcolor",
301 "termcolor",
300 ]
302 ]
301
303
302 [[package]]
304 [[package]]
303 name = "flate2"
305 name = "flate2"
304 version = "1.0.19"
306 version = "1.0.19"
305 source = "registry+https://github.com/rust-lang/crates.io-index"
307 source = "registry+https://github.com/rust-lang/crates.io-index"
306 checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
308 checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
307 dependencies = [
309 dependencies = [
308 "cfg-if 1.0.0",
310 "cfg-if 1.0.0",
309 "crc32fast",
311 "crc32fast",
310 "libc",
312 "libc",
311 "libz-sys",
313 "libz-sys",
312 "miniz_oxide",
314 "miniz_oxide",
313 ]
315 ]
314
316
315 [[package]]
317 [[package]]
316 name = "format-bytes"
318 name = "format-bytes"
317 version = "0.2.2"
319 version = "0.2.2"
318 source = "registry+https://github.com/rust-lang/crates.io-index"
320 source = "registry+https://github.com/rust-lang/crates.io-index"
319 checksum = "1c4e89040c7fd7b4e6ba2820ac705a45def8a0c098ec78d170ae88f1ef1d5762"
321 checksum = "1c4e89040c7fd7b4e6ba2820ac705a45def8a0c098ec78d170ae88f1ef1d5762"
320 dependencies = [
322 dependencies = [
321 "format-bytes-macros",
323 "format-bytes-macros",
322 "proc-macro-hack",
324 "proc-macro-hack",
323 ]
325 ]
324
326
325 [[package]]
327 [[package]]
326 name = "format-bytes-macros"
328 name = "format-bytes-macros"
327 version = "0.3.0"
329 version = "0.3.0"
328 source = "registry+https://github.com/rust-lang/crates.io-index"
330 source = "registry+https://github.com/rust-lang/crates.io-index"
329 checksum = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d"
331 checksum = "b05089e341a0460449e2210c3bf7b61597860b07f0deae58da38dbed0a4c6b6d"
330 dependencies = [
332 dependencies = [
331 "proc-macro-hack",
333 "proc-macro-hack",
332 "proc-macro2",
334 "proc-macro2",
333 "quote",
335 "quote",
334 "syn",
336 "syn",
335 ]
337 ]
336
338
337 [[package]]
339 [[package]]
338 name = "generic-array"
340 name = "generic-array"
339 version = "0.14.4"
341 version = "0.14.4"
340 source = "registry+https://github.com/rust-lang/crates.io-index"
342 source = "registry+https://github.com/rust-lang/crates.io-index"
341 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
343 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
342 dependencies = [
344 dependencies = [
343 "typenum",
345 "typenum",
344 "version_check",
346 "version_check",
345 ]
347 ]
346
348
347 [[package]]
349 [[package]]
348 name = "getrandom"
350 name = "getrandom"
349 version = "0.1.15"
351 version = "0.1.15"
350 source = "registry+https://github.com/rust-lang/crates.io-index"
352 source = "registry+https://github.com/rust-lang/crates.io-index"
351 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
353 checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
352 dependencies = [
354 dependencies = [
353 "cfg-if 0.1.10",
355 "cfg-if 0.1.10",
354 "libc",
356 "libc",
355 "wasi 0.9.0+wasi-snapshot-preview1",
357 "wasi 0.9.0+wasi-snapshot-preview1",
356 ]
358 ]
357
359
358 [[package]]
360 [[package]]
359 name = "glob"
361 name = "glob"
360 version = "0.3.0"
362 version = "0.3.0"
361 source = "registry+https://github.com/rust-lang/crates.io-index"
363 source = "registry+https://github.com/rust-lang/crates.io-index"
362 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
364 checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
363
365
364 [[package]]
366 [[package]]
365 name = "hermit-abi"
367 name = "hermit-abi"
366 version = "0.1.17"
368 version = "0.1.17"
367 source = "registry+https://github.com/rust-lang/crates.io-index"
369 source = "registry+https://github.com/rust-lang/crates.io-index"
368 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
370 checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
369 dependencies = [
371 dependencies = [
370 "libc",
372 "libc",
371 ]
373 ]
372
374
373 [[package]]
375 [[package]]
374 name = "hg-core"
376 name = "hg-core"
375 version = "0.1.0"
377 version = "0.1.0"
376 dependencies = [
378 dependencies = [
377 "byteorder",
379 "byteorder",
378 "bytes-cast",
380 "bytes-cast",
379 "clap",
381 "clap",
380 "crossbeam-channel 0.4.4",
382 "crossbeam-channel 0.4.4",
381 "derive_more",
383 "derive_more",
382 "flate2",
384 "flate2",
383 "format-bytes",
385 "format-bytes",
384 "home",
386 "home",
385 "im-rc",
387 "im-rc",
386 "itertools",
388 "itertools",
387 "lazy_static",
389 "lazy_static",
388 "log",
390 "log",
389 "memmap",
391 "memmap",
390 "micro-timer",
392 "micro-timer",
391 "pretty_assertions",
393 "pretty_assertions",
392 "rand",
394 "rand",
393 "rand_distr",
395 "rand_distr",
394 "rand_pcg",
396 "rand_pcg",
395 "rayon",
397 "rayon",
396 "regex",
398 "regex",
397 "same-file",
399 "same-file",
398 "sha-1",
400 "sha-1",
401 "stable_deref_trait",
399 "tempfile",
402 "tempfile",
400 "twox-hash",
403 "twox-hash",
401 "zstd",
404 "zstd",
402 ]
405 ]
403
406
404 [[package]]
407 [[package]]
405 name = "hg-cpython"
408 name = "hg-cpython"
406 version = "0.1.0"
409 version = "0.1.0"
407 dependencies = [
410 dependencies = [
408 "cpython",
411 "cpython",
409 "crossbeam-channel 0.4.4",
412 "crossbeam-channel 0.4.4",
410 "env_logger",
413 "env_logger",
411 "hg-core",
414 "hg-core",
412 "libc",
415 "libc",
413 "log",
416 "log",
417 "stable_deref_trait",
414 ]
418 ]
415
419
416 [[package]]
420 [[package]]
417 name = "home"
421 name = "home"
418 version = "0.5.3"
422 version = "0.5.3"
419 source = "registry+https://github.com/rust-lang/crates.io-index"
423 source = "registry+https://github.com/rust-lang/crates.io-index"
420 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
424 checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654"
421 dependencies = [
425 dependencies = [
422 "winapi",
426 "winapi",
423 ]
427 ]
424
428
425 [[package]]
429 [[package]]
426 name = "humantime"
430 name = "humantime"
427 version = "1.3.0"
431 version = "1.3.0"
428 source = "registry+https://github.com/rust-lang/crates.io-index"
432 source = "registry+https://github.com/rust-lang/crates.io-index"
429 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
433 checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
430 dependencies = [
434 dependencies = [
431 "quick-error",
435 "quick-error",
432 ]
436 ]
433
437
434 [[package]]
438 [[package]]
435 name = "im-rc"
439 name = "im-rc"
436 version = "15.0.0"
440 version = "15.0.0"
437 source = "registry+https://github.com/rust-lang/crates.io-index"
441 source = "registry+https://github.com/rust-lang/crates.io-index"
438 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
442 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
439 dependencies = [
443 dependencies = [
440 "bitmaps",
444 "bitmaps",
441 "rand_core",
445 "rand_core",
442 "rand_xoshiro",
446 "rand_xoshiro",
443 "sized-chunks",
447 "sized-chunks",
444 "typenum",
448 "typenum",
445 "version_check",
449 "version_check",
446 ]
450 ]
447
451
448 [[package]]
452 [[package]]
449 name = "itertools"
453 name = "itertools"
450 version = "0.9.0"
454 version = "0.9.0"
451 source = "registry+https://github.com/rust-lang/crates.io-index"
455 source = "registry+https://github.com/rust-lang/crates.io-index"
452 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
456 checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
453 dependencies = [
457 dependencies = [
454 "either",
458 "either",
455 ]
459 ]
456
460
457 [[package]]
461 [[package]]
458 name = "jobserver"
462 name = "jobserver"
459 version = "0.1.21"
463 version = "0.1.21"
460 source = "registry+https://github.com/rust-lang/crates.io-index"
464 source = "registry+https://github.com/rust-lang/crates.io-index"
461 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
465 checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
462 dependencies = [
466 dependencies = [
463 "libc",
467 "libc",
464 ]
468 ]
465
469
466 [[package]]
470 [[package]]
467 name = "lazy_static"
471 name = "lazy_static"
468 version = "1.4.0"
472 version = "1.4.0"
469 source = "registry+https://github.com/rust-lang/crates.io-index"
473 source = "registry+https://github.com/rust-lang/crates.io-index"
470 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
474 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
471
475
472 [[package]]
476 [[package]]
473 name = "libc"
477 name = "libc"
474 version = "0.2.81"
478 version = "0.2.81"
475 source = "registry+https://github.com/rust-lang/crates.io-index"
479 source = "registry+https://github.com/rust-lang/crates.io-index"
476 checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
480 checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
477
481
478 [[package]]
482 [[package]]
479 name = "libz-sys"
483 name = "libz-sys"
480 version = "1.1.2"
484 version = "1.1.2"
481 source = "registry+https://github.com/rust-lang/crates.io-index"
485 source = "registry+https://github.com/rust-lang/crates.io-index"
482 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
486 checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655"
483 dependencies = [
487 dependencies = [
484 "cc",
488 "cc",
485 "pkg-config",
489 "pkg-config",
486 "vcpkg",
490 "vcpkg",
487 ]
491 ]
488
492
489 [[package]]
493 [[package]]
490 name = "log"
494 name = "log"
491 version = "0.4.11"
495 version = "0.4.11"
492 source = "registry+https://github.com/rust-lang/crates.io-index"
496 source = "registry+https://github.com/rust-lang/crates.io-index"
493 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
497 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
494 dependencies = [
498 dependencies = [
495 "cfg-if 0.1.10",
499 "cfg-if 0.1.10",
496 ]
500 ]
497
501
498 [[package]]
502 [[package]]
499 name = "maybe-uninit"
503 name = "maybe-uninit"
500 version = "2.0.0"
504 version = "2.0.0"
501 source = "registry+https://github.com/rust-lang/crates.io-index"
505 source = "registry+https://github.com/rust-lang/crates.io-index"
502 checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
506 checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
503
507
504 [[package]]
508 [[package]]
505 name = "memchr"
509 name = "memchr"
506 version = "2.3.4"
510 version = "2.3.4"
507 source = "registry+https://github.com/rust-lang/crates.io-index"
511 source = "registry+https://github.com/rust-lang/crates.io-index"
508 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
512 checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
509
513
510 [[package]]
514 [[package]]
511 name = "memmap"
515 name = "memmap"
512 version = "0.7.0"
516 version = "0.7.0"
513 source = "registry+https://github.com/rust-lang/crates.io-index"
517 source = "registry+https://github.com/rust-lang/crates.io-index"
514 checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
518 checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b"
515 dependencies = [
519 dependencies = [
516 "libc",
520 "libc",
517 "winapi",
521 "winapi",
518 ]
522 ]
519
523
520 [[package]]
524 [[package]]
521 name = "memoffset"
525 name = "memoffset"
522 version = "0.6.1"
526 version = "0.6.1"
523 source = "registry+https://github.com/rust-lang/crates.io-index"
527 source = "registry+https://github.com/rust-lang/crates.io-index"
524 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
528 checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
525 dependencies = [
529 dependencies = [
526 "autocfg",
530 "autocfg",
527 ]
531 ]
528
532
529 [[package]]
533 [[package]]
530 name = "micro-timer"
534 name = "micro-timer"
531 version = "0.3.1"
535 version = "0.3.1"
532 source = "registry+https://github.com/rust-lang/crates.io-index"
536 source = "registry+https://github.com/rust-lang/crates.io-index"
533 checksum = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
537 checksum = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
534 dependencies = [
538 dependencies = [
535 "micro-timer-macros",
539 "micro-timer-macros",
536 "scopeguard",
540 "scopeguard",
537 ]
541 ]
538
542
539 [[package]]
543 [[package]]
540 name = "micro-timer-macros"
544 name = "micro-timer-macros"
541 version = "0.3.1"
545 version = "0.3.1"
542 source = "registry+https://github.com/rust-lang/crates.io-index"
546 source = "registry+https://github.com/rust-lang/crates.io-index"
543 checksum = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
547 checksum = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
544 dependencies = [
548 dependencies = [
545 "proc-macro2",
549 "proc-macro2",
546 "quote",
550 "quote",
547 "scopeguard",
551 "scopeguard",
548 "syn",
552 "syn",
549 ]
553 ]
550
554
551 [[package]]
555 [[package]]
552 name = "miniz_oxide"
556 name = "miniz_oxide"
553 version = "0.4.3"
557 version = "0.4.3"
554 source = "registry+https://github.com/rust-lang/crates.io-index"
558 source = "registry+https://github.com/rust-lang/crates.io-index"
555 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
559 checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
556 dependencies = [
560 dependencies = [
557 "adler",
561 "adler",
558 "autocfg",
562 "autocfg",
559 ]
563 ]
560
564
561 [[package]]
565 [[package]]
562 name = "num-integer"
566 name = "num-integer"
563 version = "0.1.44"
567 version = "0.1.44"
564 source = "registry+https://github.com/rust-lang/crates.io-index"
568 source = "registry+https://github.com/rust-lang/crates.io-index"
565 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
569 checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
566 dependencies = [
570 dependencies = [
567 "autocfg",
571 "autocfg",
568 "num-traits",
572 "num-traits",
569 ]
573 ]
570
574
571 [[package]]
575 [[package]]
572 name = "num-traits"
576 name = "num-traits"
573 version = "0.2.14"
577 version = "0.2.14"
574 source = "registry+https://github.com/rust-lang/crates.io-index"
578 source = "registry+https://github.com/rust-lang/crates.io-index"
575 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
579 checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
576 dependencies = [
580 dependencies = [
577 "autocfg",
581 "autocfg",
578 ]
582 ]
579
583
580 [[package]]
584 [[package]]
581 name = "num_cpus"
585 name = "num_cpus"
582 version = "1.13.0"
586 version = "1.13.0"
583 source = "registry+https://github.com/rust-lang/crates.io-index"
587 source = "registry+https://github.com/rust-lang/crates.io-index"
584 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
588 checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
585 dependencies = [
589 dependencies = [
586 "hermit-abi",
590 "hermit-abi",
587 "libc",
591 "libc",
588 ]
592 ]
589
593
590 [[package]]
594 [[package]]
591 name = "opaque-debug"
595 name = "opaque-debug"
592 version = "0.3.0"
596 version = "0.3.0"
593 source = "registry+https://github.com/rust-lang/crates.io-index"
597 source = "registry+https://github.com/rust-lang/crates.io-index"
594 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
598 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
595
599
596 [[package]]
600 [[package]]
597 name = "output_vt100"
601 name = "output_vt100"
598 version = "0.1.2"
602 version = "0.1.2"
599 source = "registry+https://github.com/rust-lang/crates.io-index"
603 source = "registry+https://github.com/rust-lang/crates.io-index"
600 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
604 checksum = "53cdc5b785b7a58c5aad8216b3dfa114df64b0b06ae6e1501cef91df2fbdf8f9"
601 dependencies = [
605 dependencies = [
602 "winapi",
606 "winapi",
603 ]
607 ]
604
608
605 [[package]]
609 [[package]]
606 name = "paste"
610 name = "paste"
607 version = "1.0.5"
611 version = "1.0.5"
608 source = "registry+https://github.com/rust-lang/crates.io-index"
612 source = "registry+https://github.com/rust-lang/crates.io-index"
609 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
613 checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58"
610
614
611 [[package]]
615 [[package]]
612 name = "pkg-config"
616 name = "pkg-config"
613 version = "0.3.19"
617 version = "0.3.19"
614 source = "registry+https://github.com/rust-lang/crates.io-index"
618 source = "registry+https://github.com/rust-lang/crates.io-index"
615 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
619 checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
616
620
617 [[package]]
621 [[package]]
618 name = "ppv-lite86"
622 name = "ppv-lite86"
619 version = "0.2.10"
623 version = "0.2.10"
620 source = "registry+https://github.com/rust-lang/crates.io-index"
624 source = "registry+https://github.com/rust-lang/crates.io-index"
621 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
625 checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
622
626
623 [[package]]
627 [[package]]
624 name = "pretty_assertions"
628 name = "pretty_assertions"
625 version = "0.6.1"
629 version = "0.6.1"
626 source = "registry+https://github.com/rust-lang/crates.io-index"
630 source = "registry+https://github.com/rust-lang/crates.io-index"
627 checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
631 checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
628 dependencies = [
632 dependencies = [
629 "ansi_term",
633 "ansi_term",
630 "ctor",
634 "ctor",
631 "difference",
635 "difference",
632 "output_vt100",
636 "output_vt100",
633 ]
637 ]
634
638
635 [[package]]
639 [[package]]
636 name = "proc-macro-hack"
640 name = "proc-macro-hack"
637 version = "0.5.19"
641 version = "0.5.19"
638 source = "registry+https://github.com/rust-lang/crates.io-index"
642 source = "registry+https://github.com/rust-lang/crates.io-index"
639 checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
643 checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
640
644
641 [[package]]
645 [[package]]
642 name = "proc-macro2"
646 name = "proc-macro2"
643 version = "1.0.24"
647 version = "1.0.24"
644 source = "registry+https://github.com/rust-lang/crates.io-index"
648 source = "registry+https://github.com/rust-lang/crates.io-index"
645 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
649 checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
646 dependencies = [
650 dependencies = [
647 "unicode-xid",
651 "unicode-xid",
648 ]
652 ]
649
653
650 [[package]]
654 [[package]]
651 name = "python27-sys"
655 name = "python27-sys"
652 version = "0.6.0"
656 version = "0.6.0"
653 source = "registry+https://github.com/rust-lang/crates.io-index"
657 source = "registry+https://github.com/rust-lang/crates.io-index"
654 checksum = "5826ddbc5366eb0b0492040fdc25bf50bb49092c192bd45e80fb7a24dc6832ab"
658 checksum = "5826ddbc5366eb0b0492040fdc25bf50bb49092c192bd45e80fb7a24dc6832ab"
655 dependencies = [
659 dependencies = [
656 "libc",
660 "libc",
657 "regex",
661 "regex",
658 ]
662 ]
659
663
660 [[package]]
664 [[package]]
661 name = "python3-sys"
665 name = "python3-sys"
662 version = "0.6.0"
666 version = "0.6.0"
663 source = "registry+https://github.com/rust-lang/crates.io-index"
667 source = "registry+https://github.com/rust-lang/crates.io-index"
664 checksum = "b78af21b29594951a47fc3dac9b9eff0a3f077dec2f780ee943ae16a668f3b6a"
668 checksum = "b78af21b29594951a47fc3dac9b9eff0a3f077dec2f780ee943ae16a668f3b6a"
665 dependencies = [
669 dependencies = [
666 "libc",
670 "libc",
667 "regex",
671 "regex",
668 ]
672 ]
669
673
670 [[package]]
674 [[package]]
671 name = "quick-error"
675 name = "quick-error"
672 version = "1.2.3"
676 version = "1.2.3"
673 source = "registry+https://github.com/rust-lang/crates.io-index"
677 source = "registry+https://github.com/rust-lang/crates.io-index"
674 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
678 checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
675
679
676 [[package]]
680 [[package]]
677 name = "quote"
681 name = "quote"
678 version = "1.0.7"
682 version = "1.0.7"
679 source = "registry+https://github.com/rust-lang/crates.io-index"
683 source = "registry+https://github.com/rust-lang/crates.io-index"
680 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
684 checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
681 dependencies = [
685 dependencies = [
682 "proc-macro2",
686 "proc-macro2",
683 ]
687 ]
684
688
685 [[package]]
689 [[package]]
686 name = "rand"
690 name = "rand"
687 version = "0.7.3"
691 version = "0.7.3"
688 source = "registry+https://github.com/rust-lang/crates.io-index"
692 source = "registry+https://github.com/rust-lang/crates.io-index"
689 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
693 checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
690 dependencies = [
694 dependencies = [
691 "getrandom",
695 "getrandom",
692 "libc",
696 "libc",
693 "rand_chacha",
697 "rand_chacha",
694 "rand_core",
698 "rand_core",
695 "rand_hc",
699 "rand_hc",
696 ]
700 ]
697
701
698 [[package]]
702 [[package]]
699 name = "rand_chacha"
703 name = "rand_chacha"
700 version = "0.2.2"
704 version = "0.2.2"
701 source = "registry+https://github.com/rust-lang/crates.io-index"
705 source = "registry+https://github.com/rust-lang/crates.io-index"
702 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
706 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
703 dependencies = [
707 dependencies = [
704 "ppv-lite86",
708 "ppv-lite86",
705 "rand_core",
709 "rand_core",
706 ]
710 ]
707
711
708 [[package]]
712 [[package]]
709 name = "rand_core"
713 name = "rand_core"
710 version = "0.5.1"
714 version = "0.5.1"
711 source = "registry+https://github.com/rust-lang/crates.io-index"
715 source = "registry+https://github.com/rust-lang/crates.io-index"
712 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
716 checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
713 dependencies = [
717 dependencies = [
714 "getrandom",
718 "getrandom",
715 ]
719 ]
716
720
717 [[package]]
721 [[package]]
718 name = "rand_distr"
722 name = "rand_distr"
719 version = "0.2.2"
723 version = "0.2.2"
720 source = "registry+https://github.com/rust-lang/crates.io-index"
724 source = "registry+https://github.com/rust-lang/crates.io-index"
721 checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
725 checksum = "96977acbdd3a6576fb1d27391900035bf3863d4a16422973a409b488cf29ffb2"
722 dependencies = [
726 dependencies = [
723 "rand",
727 "rand",
724 ]
728 ]
725
729
726 [[package]]
730 [[package]]
727 name = "rand_hc"
731 name = "rand_hc"
728 version = "0.2.0"
732 version = "0.2.0"
729 source = "registry+https://github.com/rust-lang/crates.io-index"
733 source = "registry+https://github.com/rust-lang/crates.io-index"
730 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
734 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
731 dependencies = [
735 dependencies = [
732 "rand_core",
736 "rand_core",
733 ]
737 ]
734
738
735 [[package]]
739 [[package]]
736 name = "rand_pcg"
740 name = "rand_pcg"
737 version = "0.2.1"
741 version = "0.2.1"
738 source = "registry+https://github.com/rust-lang/crates.io-index"
742 source = "registry+https://github.com/rust-lang/crates.io-index"
739 checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
743 checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
740 dependencies = [
744 dependencies = [
741 "rand_core",
745 "rand_core",
742 ]
746 ]
743
747
744 [[package]]
748 [[package]]
745 name = "rand_xoshiro"
749 name = "rand_xoshiro"
746 version = "0.4.0"
750 version = "0.4.0"
747 source = "registry+https://github.com/rust-lang/crates.io-index"
751 source = "registry+https://github.com/rust-lang/crates.io-index"
748 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
752 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
749 dependencies = [
753 dependencies = [
750 "rand_core",
754 "rand_core",
751 ]
755 ]
752
756
753 [[package]]
757 [[package]]
754 name = "rayon"
758 name = "rayon"
755 version = "1.5.0"
759 version = "1.5.0"
756 source = "registry+https://github.com/rust-lang/crates.io-index"
760 source = "registry+https://github.com/rust-lang/crates.io-index"
757 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
761 checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
758 dependencies = [
762 dependencies = [
759 "autocfg",
763 "autocfg",
760 "crossbeam-deque",
764 "crossbeam-deque",
761 "either",
765 "either",
762 "rayon-core",
766 "rayon-core",
763 ]
767 ]
764
768
765 [[package]]
769 [[package]]
766 name = "rayon-core"
770 name = "rayon-core"
767 version = "1.9.0"
771 version = "1.9.0"
768 source = "registry+https://github.com/rust-lang/crates.io-index"
772 source = "registry+https://github.com/rust-lang/crates.io-index"
769 checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
773 checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
770 dependencies = [
774 dependencies = [
771 "crossbeam-channel 0.5.0",
775 "crossbeam-channel 0.5.0",
772 "crossbeam-deque",
776 "crossbeam-deque",
773 "crossbeam-utils 0.8.1",
777 "crossbeam-utils 0.8.1",
774 "lazy_static",
778 "lazy_static",
775 "num_cpus",
779 "num_cpus",
776 ]
780 ]
777
781
778 [[package]]
782 [[package]]
779 name = "redox_syscall"
783 name = "redox_syscall"
780 version = "0.1.57"
784 version = "0.1.57"
781 source = "registry+https://github.com/rust-lang/crates.io-index"
785 source = "registry+https://github.com/rust-lang/crates.io-index"
782 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
786 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
783
787
784 [[package]]
788 [[package]]
785 name = "regex"
789 name = "regex"
786 version = "1.4.2"
790 version = "1.4.2"
787 source = "registry+https://github.com/rust-lang/crates.io-index"
791 source = "registry+https://github.com/rust-lang/crates.io-index"
788 checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
792 checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
789 dependencies = [
793 dependencies = [
790 "aho-corasick",
794 "aho-corasick",
791 "memchr",
795 "memchr",
792 "regex-syntax",
796 "regex-syntax",
793 "thread_local",
797 "thread_local",
794 ]
798 ]
795
799
796 [[package]]
800 [[package]]
797 name = "regex-syntax"
801 name = "regex-syntax"
798 version = "0.6.21"
802 version = "0.6.21"
799 source = "registry+https://github.com/rust-lang/crates.io-index"
803 source = "registry+https://github.com/rust-lang/crates.io-index"
800 checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
804 checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
801
805
802 [[package]]
806 [[package]]
803 name = "remove_dir_all"
807 name = "remove_dir_all"
804 version = "0.5.3"
808 version = "0.5.3"
805 source = "registry+https://github.com/rust-lang/crates.io-index"
809 source = "registry+https://github.com/rust-lang/crates.io-index"
806 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
810 checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
807 dependencies = [
811 dependencies = [
808 "winapi",
812 "winapi",
809 ]
813 ]
810
814
811 [[package]]
815 [[package]]
812 name = "rhg"
816 name = "rhg"
813 version = "0.1.0"
817 version = "0.1.0"
814 dependencies = [
818 dependencies = [
815 "chrono",
819 "chrono",
816 "clap",
820 "clap",
817 "derive_more",
821 "derive_more",
818 "env_logger",
822 "env_logger",
819 "format-bytes",
823 "format-bytes",
820 "hg-core",
824 "hg-core",
821 "home",
825 "home",
822 "lazy_static",
826 "lazy_static",
823 "log",
827 "log",
824 "micro-timer",
828 "micro-timer",
825 "regex",
829 "regex",
826 "users",
830 "users",
827 ]
831 ]
828
832
829 [[package]]
833 [[package]]
830 name = "same-file"
834 name = "same-file"
831 version = "1.0.6"
835 version = "1.0.6"
832 source = "registry+https://github.com/rust-lang/crates.io-index"
836 source = "registry+https://github.com/rust-lang/crates.io-index"
833 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
837 checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
834 dependencies = [
838 dependencies = [
835 "winapi-util",
839 "winapi-util",
836 ]
840 ]
837
841
838 [[package]]
842 [[package]]
839 name = "scopeguard"
843 name = "scopeguard"
840 version = "1.1.0"
844 version = "1.1.0"
841 source = "registry+https://github.com/rust-lang/crates.io-index"
845 source = "registry+https://github.com/rust-lang/crates.io-index"
842 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
846 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
843
847
844 [[package]]
848 [[package]]
845 name = "sha-1"
849 name = "sha-1"
846 version = "0.9.6"
850 version = "0.9.6"
847 source = "registry+https://github.com/rust-lang/crates.io-index"
851 source = "registry+https://github.com/rust-lang/crates.io-index"
848 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
852 checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
849 dependencies = [
853 dependencies = [
850 "block-buffer",
854 "block-buffer",
851 "cfg-if 1.0.0",
855 "cfg-if 1.0.0",
852 "cpufeatures",
856 "cpufeatures",
853 "digest",
857 "digest",
854 "opaque-debug",
858 "opaque-debug",
855 ]
859 ]
856
860
857 [[package]]
861 [[package]]
858 name = "sized-chunks"
862 name = "sized-chunks"
859 version = "0.6.2"
863 version = "0.6.2"
860 source = "registry+https://github.com/rust-lang/crates.io-index"
864 source = "registry+https://github.com/rust-lang/crates.io-index"
861 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
865 checksum = "1ec31ceca5644fa6d444cc77548b88b67f46db6f7c71683b0f9336e671830d2f"
862 dependencies = [
866 dependencies = [
863 "bitmaps",
867 "bitmaps",
864 "typenum",
868 "typenum",
865 ]
869 ]
866
870
867 [[package]]
871 [[package]]
872 name = "stable_deref_trait"
873 version = "1.2.0"
874 source = "registry+https://github.com/rust-lang/crates.io-index"
875 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
876
877 [[package]]
868 name = "static_assertions"
878 name = "static_assertions"
869 version = "1.1.0"
879 version = "1.1.0"
870 source = "registry+https://github.com/rust-lang/crates.io-index"
880 source = "registry+https://github.com/rust-lang/crates.io-index"
871 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
881 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
872
882
873 [[package]]
883 [[package]]
874 name = "strsim"
884 name = "strsim"
875 version = "0.8.0"
885 version = "0.8.0"
876 source = "registry+https://github.com/rust-lang/crates.io-index"
886 source = "registry+https://github.com/rust-lang/crates.io-index"
877 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
887 checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
878
888
879 [[package]]
889 [[package]]
880 name = "syn"
890 name = "syn"
881 version = "1.0.54"
891 version = "1.0.54"
882 source = "registry+https://github.com/rust-lang/crates.io-index"
892 source = "registry+https://github.com/rust-lang/crates.io-index"
883 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
893 checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
884 dependencies = [
894 dependencies = [
885 "proc-macro2",
895 "proc-macro2",
886 "quote",
896 "quote",
887 "unicode-xid",
897 "unicode-xid",
888 ]
898 ]
889
899
890 [[package]]
900 [[package]]
891 name = "tempfile"
901 name = "tempfile"
892 version = "3.1.0"
902 version = "3.1.0"
893 source = "registry+https://github.com/rust-lang/crates.io-index"
903 source = "registry+https://github.com/rust-lang/crates.io-index"
894 checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
904 checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
895 dependencies = [
905 dependencies = [
896 "cfg-if 0.1.10",
906 "cfg-if 0.1.10",
897 "libc",
907 "libc",
898 "rand",
908 "rand",
899 "redox_syscall",
909 "redox_syscall",
900 "remove_dir_all",
910 "remove_dir_all",
901 "winapi",
911 "winapi",
902 ]
912 ]
903
913
904 [[package]]
914 [[package]]
905 name = "termcolor"
915 name = "termcolor"
906 version = "1.1.2"
916 version = "1.1.2"
907 source = "registry+https://github.com/rust-lang/crates.io-index"
917 source = "registry+https://github.com/rust-lang/crates.io-index"
908 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
918 checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
909 dependencies = [
919 dependencies = [
910 "winapi-util",
920 "winapi-util",
911 ]
921 ]
912
922
913 [[package]]
923 [[package]]
914 name = "textwrap"
924 name = "textwrap"
915 version = "0.11.0"
925 version = "0.11.0"
916 source = "registry+https://github.com/rust-lang/crates.io-index"
926 source = "registry+https://github.com/rust-lang/crates.io-index"
917 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
927 checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
918 dependencies = [
928 dependencies = [
919 "unicode-width",
929 "unicode-width",
920 ]
930 ]
921
931
922 [[package]]
932 [[package]]
923 name = "thread_local"
933 name = "thread_local"
924 version = "1.0.1"
934 version = "1.0.1"
925 source = "registry+https://github.com/rust-lang/crates.io-index"
935 source = "registry+https://github.com/rust-lang/crates.io-index"
926 checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
936 checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
927 dependencies = [
937 dependencies = [
928 "lazy_static",
938 "lazy_static",
929 ]
939 ]
930
940
931 [[package]]
941 [[package]]
932 name = "time"
942 name = "time"
933 version = "0.1.44"
943 version = "0.1.44"
934 source = "registry+https://github.com/rust-lang/crates.io-index"
944 source = "registry+https://github.com/rust-lang/crates.io-index"
935 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
945 checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
936 dependencies = [
946 dependencies = [
937 "libc",
947 "libc",
938 "wasi 0.10.0+wasi-snapshot-preview1",
948 "wasi 0.10.0+wasi-snapshot-preview1",
939 "winapi",
949 "winapi",
940 ]
950 ]
941
951
942 [[package]]
952 [[package]]
943 name = "twox-hash"
953 name = "twox-hash"
944 version = "1.6.0"
954 version = "1.6.0"
945 source = "registry+https://github.com/rust-lang/crates.io-index"
955 source = "registry+https://github.com/rust-lang/crates.io-index"
946 checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
956 checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
947 dependencies = [
957 dependencies = [
948 "cfg-if 0.1.10",
958 "cfg-if 0.1.10",
949 "rand",
959 "rand",
950 "static_assertions",
960 "static_assertions",
951 ]
961 ]
952
962
953 [[package]]
963 [[package]]
954 name = "typenum"
964 name = "typenum"
955 version = "1.12.0"
965 version = "1.12.0"
956 source = "registry+https://github.com/rust-lang/crates.io-index"
966 source = "registry+https://github.com/rust-lang/crates.io-index"
957 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
967 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
958
968
959 [[package]]
969 [[package]]
960 name = "unicode-width"
970 name = "unicode-width"
961 version = "0.1.8"
971 version = "0.1.8"
962 source = "registry+https://github.com/rust-lang/crates.io-index"
972 source = "registry+https://github.com/rust-lang/crates.io-index"
963 checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
973 checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
964
974
965 [[package]]
975 [[package]]
966 name = "unicode-xid"
976 name = "unicode-xid"
967 version = "0.2.1"
977 version = "0.2.1"
968 source = "registry+https://github.com/rust-lang/crates.io-index"
978 source = "registry+https://github.com/rust-lang/crates.io-index"
969 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
979 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
970
980
971 [[package]]
981 [[package]]
972 name = "users"
982 name = "users"
973 version = "0.11.0"
983 version = "0.11.0"
974 source = "registry+https://github.com/rust-lang/crates.io-index"
984 source = "registry+https://github.com/rust-lang/crates.io-index"
975 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
985 checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
976 dependencies = [
986 dependencies = [
977 "libc",
987 "libc",
978 "log",
988 "log",
979 ]
989 ]
980
990
981 [[package]]
991 [[package]]
982 name = "vcpkg"
992 name = "vcpkg"
983 version = "0.2.11"
993 version = "0.2.11"
984 source = "registry+https://github.com/rust-lang/crates.io-index"
994 source = "registry+https://github.com/rust-lang/crates.io-index"
985 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
995 checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
986
996
987 [[package]]
997 [[package]]
988 name = "vec_map"
998 name = "vec_map"
989 version = "0.8.2"
999 version = "0.8.2"
990 source = "registry+https://github.com/rust-lang/crates.io-index"
1000 source = "registry+https://github.com/rust-lang/crates.io-index"
991 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1001 checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
992
1002
993 [[package]]
1003 [[package]]
994 name = "version_check"
1004 name = "version_check"
995 version = "0.9.2"
1005 version = "0.9.2"
996 source = "registry+https://github.com/rust-lang/crates.io-index"
1006 source = "registry+https://github.com/rust-lang/crates.io-index"
997 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
1007 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
998
1008
999 [[package]]
1009 [[package]]
1000 name = "wasi"
1010 name = "wasi"
1001 version = "0.9.0+wasi-snapshot-preview1"
1011 version = "0.9.0+wasi-snapshot-preview1"
1002 source = "registry+https://github.com/rust-lang/crates.io-index"
1012 source = "registry+https://github.com/rust-lang/crates.io-index"
1003 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1013 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1004
1014
1005 [[package]]
1015 [[package]]
1006 name = "wasi"
1016 name = "wasi"
1007 version = "0.10.0+wasi-snapshot-preview1"
1017 version = "0.10.0+wasi-snapshot-preview1"
1008 source = "registry+https://github.com/rust-lang/crates.io-index"
1018 source = "registry+https://github.com/rust-lang/crates.io-index"
1009 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1019 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1010
1020
1011 [[package]]
1021 [[package]]
1012 name = "winapi"
1022 name = "winapi"
1013 version = "0.3.9"
1023 version = "0.3.9"
1014 source = "registry+https://github.com/rust-lang/crates.io-index"
1024 source = "registry+https://github.com/rust-lang/crates.io-index"
1015 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1025 checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1016 dependencies = [
1026 dependencies = [
1017 "winapi-i686-pc-windows-gnu",
1027 "winapi-i686-pc-windows-gnu",
1018 "winapi-x86_64-pc-windows-gnu",
1028 "winapi-x86_64-pc-windows-gnu",
1019 ]
1029 ]
1020
1030
1021 [[package]]
1031 [[package]]
1022 name = "winapi-i686-pc-windows-gnu"
1032 name = "winapi-i686-pc-windows-gnu"
1023 version = "0.4.0"
1033 version = "0.4.0"
1024 source = "registry+https://github.com/rust-lang/crates.io-index"
1034 source = "registry+https://github.com/rust-lang/crates.io-index"
1025 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1035 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1026
1036
1027 [[package]]
1037 [[package]]
1028 name = "winapi-util"
1038 name = "winapi-util"
1029 version = "0.1.5"
1039 version = "0.1.5"
1030 source = "registry+https://github.com/rust-lang/crates.io-index"
1040 source = "registry+https://github.com/rust-lang/crates.io-index"
1031 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1041 checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1032 dependencies = [
1042 dependencies = [
1033 "winapi",
1043 "winapi",
1034 ]
1044 ]
1035
1045
1036 [[package]]
1046 [[package]]
1037 name = "winapi-x86_64-pc-windows-gnu"
1047 name = "winapi-x86_64-pc-windows-gnu"
1038 version = "0.4.0"
1048 version = "0.4.0"
1039 source = "registry+https://github.com/rust-lang/crates.io-index"
1049 source = "registry+https://github.com/rust-lang/crates.io-index"
1040 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1050 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1041
1051
1042 [[package]]
1052 [[package]]
1043 name = "zstd"
1053 name = "zstd"
1044 version = "0.5.3+zstd.1.4.5"
1054 version = "0.5.3+zstd.1.4.5"
1045 source = "registry+https://github.com/rust-lang/crates.io-index"
1055 source = "registry+https://github.com/rust-lang/crates.io-index"
1046 checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
1056 checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
1047 dependencies = [
1057 dependencies = [
1048 "zstd-safe",
1058 "zstd-safe",
1049 ]
1059 ]
1050
1060
1051 [[package]]
1061 [[package]]
1052 name = "zstd-safe"
1062 name = "zstd-safe"
1053 version = "2.0.5+zstd.1.4.5"
1063 version = "2.0.5+zstd.1.4.5"
1054 source = "registry+https://github.com/rust-lang/crates.io-index"
1064 source = "registry+https://github.com/rust-lang/crates.io-index"
1055 checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
1065 checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
1056 dependencies = [
1066 dependencies = [
1057 "libc",
1067 "libc",
1058 "zstd-sys",
1068 "zstd-sys",
1059 ]
1069 ]
1060
1070
1061 [[package]]
1071 [[package]]
1062 name = "zstd-sys"
1072 name = "zstd-sys"
1063 version = "1.4.17+zstd.1.4.5"
1073 version = "1.4.17+zstd.1.4.5"
1064 source = "registry+https://github.com/rust-lang/crates.io-index"
1074 source = "registry+https://github.com/rust-lang/crates.io-index"
1065 checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
1075 checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
1066 dependencies = [
1076 dependencies = [
1067 "cc",
1077 "cc",
1068 "glob",
1078 "glob",
1069 "itertools",
1079 "itertools",
1070 "libc",
1080 "libc",
1071 ]
1081 ]
@@ -1,44 +1,45 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 bytes-cast = "0.2"
12 bytes-cast = "0.2"
13 byteorder = "1.3.4"
13 byteorder = "1.3.4"
14 derive_more = "0.99"
14 derive_more = "0.99"
15 home = "0.5"
15 home = "0.5"
16 im-rc = "15.0.*"
16 im-rc = "15.0.*"
17 itertools = "0.9"
17 itertools = "0.9"
18 lazy_static = "1.4.0"
18 lazy_static = "1.4.0"
19 rand = "0.7.3"
19 rand = "0.7.3"
20 rand_pcg = "0.2.1"
20 rand_pcg = "0.2.1"
21 rand_distr = "0.2.2"
21 rand_distr = "0.2.2"
22 rayon = "1.3.0"
22 rayon = "1.3.0"
23 regex = "1.3.9"
23 regex = "1.3.9"
24 sha-1 = "0.9.6"
24 sha-1 = "0.9.6"
25 twox-hash = "1.5.0"
25 twox-hash = "1.5.0"
26 same-file = "1.0.6"
26 same-file = "1.0.6"
27 stable_deref_trait = "1.2.0"
27 tempfile = "3.1.0"
28 tempfile = "3.1.0"
28 crossbeam-channel = "0.4"
29 crossbeam-channel = "0.4"
29 micro-timer = "0.3.0"
30 micro-timer = "0.3.0"
30 log = "0.4.8"
31 log = "0.4.8"
31 memmap = "0.7.0"
32 memmap = "0.7.0"
32 zstd = "0.5.3"
33 zstd = "0.5.3"
33 format-bytes = "0.2.2"
34 format-bytes = "0.2.2"
34
35
35 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
36 # We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
36 # we have a clearer view of which backend is the fastest.
37 # we have a clearer view of which backend is the fastest.
37 [dependencies.flate2]
38 [dependencies.flate2]
38 version = "1.0.16"
39 version = "1.0.16"
39 features = ["zlib"]
40 features = ["zlib"]
40 default-features = false
41 default-features = false
41
42
42 [dev-dependencies]
43 [dev-dependencies]
43 clap = "*"
44 clap = "*"
44 pretty_assertions = "0.6.1"
45 pretty_assertions = "0.6.1"
@@ -1,5 +1,7 b''
1 pub mod dirstate_map;
1 pub mod dirstate_map;
2 pub mod dispatch;
2 pub mod dispatch;
3 pub mod on_disk;
3 pub mod on_disk;
4 pub mod owning;
5 mod owning_dispatch;
4 pub mod path_with_basename;
6 pub mod path_with_basename;
5 pub mod status;
7 pub mod status;
@@ -1,117 +1,105 b''
1 use cpython::PyBytes;
1 use super::dirstate_map::DirstateMap;
2 use cpython::Python;
2 use stable_deref_trait::StableDeref;
3 use hg::dirstate_tree::dirstate_map::DirstateMap;
3 use std::ops::Deref;
4 use hg::DirstateError;
5 use hg::DirstateParents;
6
4
7 /// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it
5 /// Keep a `DirstateMap<'on_disk>` next to the `on_disk` buffer that it
8 /// borrows. This is similar to the owning-ref crate.
6 /// borrows.
9 ///
7 ///
10 /// This is similar to [`OwningRef`] which is more limited because it
8 /// This is similar to [`OwningRef`] which is more limited because it
11 /// represents exactly one `&T` reference next to the value it borrows, as
9 /// represents exactly one `&T` reference next to the value it borrows, as
12 /// opposed to a struct that may contain an arbitrary number of references in
10 /// opposed to a struct that may contain an arbitrary number of references in
13 /// arbitrarily-nested data structures.
11 /// arbitrarily-nested data structures.
14 ///
12 ///
15 /// [`OwningRef`]: https://docs.rs/owning_ref/0.4.1/owning_ref/struct.OwningRef.html
13 /// [`OwningRef`]: https://docs.rs/owning_ref/0.4.1/owning_ref/struct.OwningRef.html
16 pub(super) struct OwningDirstateMap {
14 pub struct OwningDirstateMap {
17 /// Owned handle to a bytes buffer with a stable address.
15 /// Owned handle to a bytes buffer with a stable address.
18 ///
16 ///
19 /// See <https://docs.rs/owning_ref/0.4.1/owning_ref/trait.StableAddress.html>.
17 /// See <https://docs.rs/owning_ref/0.4.1/owning_ref/trait.StableAddress.html>.
20 on_disk: PyBytes,
18 on_disk: Box<dyn Deref<Target = [u8]> + Send>,
21
19
22 /// Pointer for `Box<DirstateMap<'on_disk>>`, typed-erased because the
20 /// Pointer for `Box<DirstateMap<'on_disk>>`, typed-erased because the
23 /// language cannot represent a lifetime referencing a sibling field.
21 /// language cannot represent a lifetime referencing a sibling field.
24 /// This is not quite a self-referencial struct (moving this struct is not
22 /// This is not quite a self-referencial struct (moving this struct is not
25 /// a problem as it doesn’t change the address of the bytes buffer owned
23 /// a problem as it doesn’t change the address of the bytes buffer owned
26 /// by `PyBytes`) but touches similar borrow-checker limitations.
24 /// by `PyBytes`) but touches similar borrow-checker limitations.
27 ptr: *mut (),
25 ptr: *mut (),
28 }
26 }
29
27
30 impl OwningDirstateMap {
28 impl OwningDirstateMap {
31 pub fn new_v1(
29 pub fn new_empty<OnDisk>(on_disk: OnDisk) -> Self
32 py: Python,
30 where
33 on_disk: PyBytes,
31 OnDisk: Deref<Target = [u8]> + StableDeref + Send + 'static,
34 ) -> Result<(Self, Option<DirstateParents>), DirstateError> {
32 {
35 let bytes: &'_ [u8] = on_disk.data(py);
33 let on_disk = Box::new(on_disk);
36 let (map, parents) = DirstateMap::new_v1(bytes)?;
34 let bytes: &'_ [u8] = &on_disk;
35 let map = DirstateMap::empty(bytes);
37
36
38 // Like in `bytes` above, this `'_` lifetime parameter borrows from
37 // Like in `bytes` above, this `'_` lifetime parameter borrows from
39 // the bytes buffer owned by `on_disk`.
38 // the bytes buffer owned by `on_disk`.
40 let ptr: *mut DirstateMap<'_> = Box::into_raw(Box::new(map));
39 let ptr: *mut DirstateMap<'_> = Box::into_raw(Box::new(map));
41
40
42 // Erase the pointed type entirely in order to erase the lifetime.
41 // Erase the pointed type entirely in order to erase the lifetime.
43 let ptr: *mut () = ptr.cast();
42 let ptr: *mut () = ptr.cast();
44
43
45 Ok((Self { on_disk, ptr }, parents))
44 Self { on_disk, ptr }
46 }
45 }
47
46
48 pub fn new_v2(
47 pub fn get_mut_pair<'a>(
49 py: Python,
48 &'a mut self,
50 on_disk: PyBytes,
49 ) -> (&'a [u8], &'a mut DirstateMap<'a>) {
51 data_size: usize,
52 tree_metadata: PyBytes,
53 ) -> Result<Self, DirstateError> {
54 let bytes: &'_ [u8] = on_disk.data(py);
55 let map =
56 DirstateMap::new_v2(bytes, data_size, tree_metadata.data(py))?;
57
58 // Like in `bytes` above, this `'_` lifetime parameter borrows from
59 // the bytes buffer owned by `on_disk`.
60 let ptr: *mut DirstateMap<'_> = Box::into_raw(Box::new(map));
61
62 // Erase the pointed type entirely in order to erase the lifetime.
63 let ptr: *mut () = ptr.cast();
64
65 Ok(Self { on_disk, ptr })
66 }
67
68 pub fn get_mut<'a>(&'a mut self) -> &'a mut DirstateMap<'a> {
69 // SAFETY: We cast the type-erased pointer back to the same type it had
50 // SAFETY: We cast the type-erased pointer back to the same type it had
70 // in `new`, except with a different lifetime parameter. This time we
51 // in `new`, except with a different lifetime parameter. This time we
71 // connect the lifetime to that of `self`. This cast is valid because
52 // connect the lifetime to that of `self`. This cast is valid because
72 // `self` owns the same `PyBytes` whose buffer `DirstateMap`
53 // `self` owns the same `PyBytes` whose buffer `DirstateMap`
73 // references. That buffer has a stable memory address because the byte
54 // references. That buffer has a stable memory address because the byte
74 // string value of a `PyBytes` is immutable.
55 // string value of a `PyBytes` is immutable.
75 let ptr: *mut DirstateMap<'a> = self.ptr.cast();
56 let ptr: *mut DirstateMap<'a> = self.ptr.cast();
76 // SAFETY: we dereference that pointer, connecting the lifetime of the
57 // SAFETY: we dereference that pointer, connecting the lifetime of the
77 // new `&mut` to that of `self`. This is valid because the
58 // new `&mut` to that of `self`. This is valid because the
78 // raw pointer is to a boxed value, and `self` owns that box.
59 // raw pointer is to a boxed value, and `self` owns that box.
79 unsafe { &mut *ptr }
60 (&self.on_disk, unsafe { &mut *ptr })
61 }
62
63 pub fn get_mut<'a>(&'a mut self) -> &'a mut DirstateMap<'a> {
64 self.get_mut_pair().1
80 }
65 }
81
66
82 pub fn get<'a>(&'a self) -> &'a DirstateMap<'a> {
67 pub fn get<'a>(&'a self) -> &'a DirstateMap<'a> {
83 // SAFETY: same reasoning as in `get_mut` above.
68 // SAFETY: same reasoning as in `get_mut` above.
84 let ptr: *mut DirstateMap<'a> = self.ptr.cast();
69 let ptr: *mut DirstateMap<'a> = self.ptr.cast();
85 unsafe { &*ptr }
70 unsafe { &*ptr }
86 }
71 }
72
73 pub fn on_disk<'a>(&'a self) -> &'a [u8] {
74 &self.on_disk
75 }
87 }
76 }
88
77
89 impl Drop for OwningDirstateMap {
78 impl Drop for OwningDirstateMap {
90 fn drop(&mut self) {
79 fn drop(&mut self) {
91 // Silence a "field is never read" warning, and demonstrate that this
80 // Silence a "field is never read" warning, and demonstrate that this
92 // value is still alive.
81 // value is still alive.
93 let _ = &self.on_disk;
82 let _ = &self.on_disk;
94 // SAFETY: this cast is the same as in `get_mut`, and is valid for the
83 // SAFETY: this cast is the same as in `get_mut`, and is valid for the
95 // same reason. `self.on_disk` still exists at this point, drop glue
84 // same reason. `self.on_disk` still exists at this point, drop glue
96 // will drop it implicitly after this `drop` method returns.
85 // will drop it implicitly after this `drop` method returns.
97 let ptr: *mut DirstateMap<'_> = self.ptr.cast();
86 let ptr: *mut DirstateMap<'_> = self.ptr.cast();
98 // SAFETY: `Box::from_raw` takes ownership of the box away from `self`.
87 // SAFETY: `Box::from_raw` takes ownership of the box away from `self`.
99 // This is fine because drop glue does nothig for `*mut ()` and we’re
88 // This is fine because drop glue does nothig for `*mut ()` and we’re
100 // in `drop`, so `get` and `get_mut` cannot be called again.
89 // in `drop`, so `get` and `get_mut` cannot be called again.
101 unsafe { drop(Box::from_raw(ptr)) }
90 unsafe { drop(Box::from_raw(ptr)) }
102 }
91 }
103 }
92 }
104
93
105 fn _static_assert_is_send<T: Send>() {}
94 fn _static_assert_is_send<T: Send>() {}
106
95
107 fn _static_assert_fields_are_send() {
96 fn _static_assert_fields_are_send() {
108 _static_assert_is_send::<PyBytes>();
109 _static_assert_is_send::<Box<DirstateMap<'_>>>();
97 _static_assert_is_send::<Box<DirstateMap<'_>>>();
110 }
98 }
111
99
112 // SAFETY: we don’t get this impl implicitly because `*mut (): !Send` because
100 // SAFETY: we don’t get this impl implicitly because `*mut (): !Send` because
113 // thread-safety of raw pointers is unknown in the general case. However this
101 // thread-safety of raw pointers is unknown in the general case. However this
114 // particular raw pointer represents a `Box<DirstateMap<'on_disk>>` that we
102 // particular raw pointer represents a `Box<DirstateMap<'on_disk>>` that we
115 // own. Since that `Box` and `PyBytes` are both `Send` as shown in above, it
103 // own. Since that `Box` is `Send` as shown in above, it is sound to mark
116 // is sound to mark this struct as `Send` too.
104 // this struct as `Send` too.
117 unsafe impl Send for OwningDirstateMap {}
105 unsafe impl Send for OwningDirstateMap {}
@@ -1,240 +1,240 b''
1 use crate::dirstate::owning::OwningDirstateMap;
1 use crate::dirstate::parsers::Timestamp;
2 use hg::dirstate::parsers::Timestamp;
2 use crate::dirstate_tree::dispatch::DirstateMapMethods;
3 use hg::dirstate_tree::dispatch::DirstateMapMethods;
3 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
4 use hg::dirstate_tree::on_disk::DirstateV2ParseError;
4 use crate::dirstate_tree::owning::OwningDirstateMap;
5 use hg::matchers::Matcher;
5 use crate::matchers::Matcher;
6 use hg::utils::hg_path::{HgPath, HgPathBuf};
6 use crate::utils::hg_path::{HgPath, HgPathBuf};
7 use hg::CopyMapIter;
7 use crate::CopyMapIter;
8 use hg::DirstateEntry;
8 use crate::DirstateEntry;
9 use hg::DirstateError;
9 use crate::DirstateError;
10 use hg::DirstateParents;
10 use crate::DirstateParents;
11 use hg::DirstateStatus;
11 use crate::DirstateStatus;
12 use hg::PatternFileWarning;
12 use crate::PatternFileWarning;
13 use hg::StateMapIter;
13 use crate::StateMapIter;
14 use hg::StatusError;
14 use crate::StatusError;
15 use hg::StatusOptions;
15 use crate::StatusOptions;
16 use std::path::PathBuf;
16 use std::path::PathBuf;
17
17
18 impl DirstateMapMethods for OwningDirstateMap {
18 impl DirstateMapMethods for OwningDirstateMap {
19 fn clear(&mut self) {
19 fn clear(&mut self) {
20 self.get_mut().clear()
20 self.get_mut().clear()
21 }
21 }
22
22
23 fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) {
23 fn set_v1(&mut self, filename: &HgPath, entry: DirstateEntry) {
24 self.get_mut().set_v1(filename, entry)
24 self.get_mut().set_v1(filename, entry)
25 }
25 }
26
26
27 fn add_file(
27 fn add_file(
28 &mut self,
28 &mut self,
29 filename: &HgPath,
29 filename: &HgPath,
30 entry: DirstateEntry,
30 entry: DirstateEntry,
31 added: bool,
31 added: bool,
32 merged: bool,
32 merged: bool,
33 from_p2: bool,
33 from_p2: bool,
34 possibly_dirty: bool,
34 possibly_dirty: bool,
35 ) -> Result<(), DirstateError> {
35 ) -> Result<(), DirstateError> {
36 self.get_mut().add_file(
36 self.get_mut().add_file(
37 filename,
37 filename,
38 entry,
38 entry,
39 added,
39 added,
40 merged,
40 merged,
41 from_p2,
41 from_p2,
42 possibly_dirty,
42 possibly_dirty,
43 )
43 )
44 }
44 }
45
45
46 fn remove_file(
46 fn remove_file(
47 &mut self,
47 &mut self,
48 filename: &HgPath,
48 filename: &HgPath,
49 in_merge: bool,
49 in_merge: bool,
50 ) -> Result<(), DirstateError> {
50 ) -> Result<(), DirstateError> {
51 self.get_mut().remove_file(filename, in_merge)
51 self.get_mut().remove_file(filename, in_merge)
52 }
52 }
53
53
54 fn drop_file(&mut self, filename: &HgPath) -> Result<bool, DirstateError> {
54 fn drop_file(&mut self, filename: &HgPath) -> Result<bool, DirstateError> {
55 self.get_mut().drop_file(filename)
55 self.get_mut().drop_file(filename)
56 }
56 }
57
57
58 fn clear_ambiguous_times(
58 fn clear_ambiguous_times(
59 &mut self,
59 &mut self,
60 filenames: Vec<HgPathBuf>,
60 filenames: Vec<HgPathBuf>,
61 now: i32,
61 now: i32,
62 ) -> Result<(), DirstateV2ParseError> {
62 ) -> Result<(), DirstateV2ParseError> {
63 self.get_mut().clear_ambiguous_times(filenames, now)
63 self.get_mut().clear_ambiguous_times(filenames, now)
64 }
64 }
65
65
66 fn non_normal_entries_contains(
66 fn non_normal_entries_contains(
67 &mut self,
67 &mut self,
68 key: &HgPath,
68 key: &HgPath,
69 ) -> Result<bool, DirstateV2ParseError> {
69 ) -> Result<bool, DirstateV2ParseError> {
70 self.get_mut().non_normal_entries_contains(key)
70 self.get_mut().non_normal_entries_contains(key)
71 }
71 }
72
72
73 fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool {
73 fn non_normal_entries_remove(&mut self, key: &HgPath) -> bool {
74 self.get_mut().non_normal_entries_remove(key)
74 self.get_mut().non_normal_entries_remove(key)
75 }
75 }
76
76
77 fn non_normal_entries_add(&mut self, key: &HgPath) {
77 fn non_normal_entries_add(&mut self, key: &HgPath) {
78 self.get_mut().non_normal_entries_add(key)
78 self.get_mut().non_normal_entries_add(key)
79 }
79 }
80
80
81 fn non_normal_or_other_parent_paths(
81 fn non_normal_or_other_parent_paths(
82 &mut self,
82 &mut self,
83 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>
83 ) -> Box<dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + '_>
84 {
84 {
85 self.get_mut().non_normal_or_other_parent_paths()
85 self.get_mut().non_normal_or_other_parent_paths()
86 }
86 }
87
87
88 fn set_non_normal_other_parent_entries(&mut self, force: bool) {
88 fn set_non_normal_other_parent_entries(&mut self, force: bool) {
89 self.get_mut().set_non_normal_other_parent_entries(force)
89 self.get_mut().set_non_normal_other_parent_entries(force)
90 }
90 }
91
91
92 fn iter_non_normal_paths(
92 fn iter_non_normal_paths(
93 &mut self,
93 &mut self,
94 ) -> Box<
94 ) -> Box<
95 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
95 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
96 > {
96 > {
97 self.get_mut().iter_non_normal_paths()
97 self.get_mut().iter_non_normal_paths()
98 }
98 }
99
99
100 fn iter_non_normal_paths_panic(
100 fn iter_non_normal_paths_panic(
101 &self,
101 &self,
102 ) -> Box<
102 ) -> Box<
103 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
103 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
104 > {
104 > {
105 self.get().iter_non_normal_paths_panic()
105 self.get().iter_non_normal_paths_panic()
106 }
106 }
107
107
108 fn iter_other_parent_paths(
108 fn iter_other_parent_paths(
109 &mut self,
109 &mut self,
110 ) -> Box<
110 ) -> Box<
111 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
111 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>> + Send + '_,
112 > {
112 > {
113 self.get_mut().iter_other_parent_paths()
113 self.get_mut().iter_other_parent_paths()
114 }
114 }
115
115
116 fn has_tracked_dir(
116 fn has_tracked_dir(
117 &mut self,
117 &mut self,
118 directory: &HgPath,
118 directory: &HgPath,
119 ) -> Result<bool, DirstateError> {
119 ) -> Result<bool, DirstateError> {
120 self.get_mut().has_tracked_dir(directory)
120 self.get_mut().has_tracked_dir(directory)
121 }
121 }
122
122
123 fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError> {
123 fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError> {
124 self.get_mut().has_dir(directory)
124 self.get_mut().has_dir(directory)
125 }
125 }
126
126
127 fn pack_v1(
127 fn pack_v1(
128 &mut self,
128 &mut self,
129 parents: DirstateParents,
129 parents: DirstateParents,
130 now: Timestamp,
130 now: Timestamp,
131 ) -> Result<Vec<u8>, DirstateError> {
131 ) -> Result<Vec<u8>, DirstateError> {
132 self.get_mut().pack_v1(parents, now)
132 self.get_mut().pack_v1(parents, now)
133 }
133 }
134
134
135 fn pack_v2(
135 fn pack_v2(
136 &mut self,
136 &mut self,
137 now: Timestamp,
137 now: Timestamp,
138 can_append: bool,
138 can_append: bool,
139 ) -> Result<(Vec<u8>, Vec<u8>, bool), DirstateError> {
139 ) -> Result<(Vec<u8>, Vec<u8>, bool), DirstateError> {
140 self.get_mut().pack_v2(now, can_append)
140 self.get_mut().pack_v2(now, can_append)
141 }
141 }
142
142
143 fn status<'a>(
143 fn status<'a>(
144 &'a mut self,
144 &'a mut self,
145 matcher: &'a (dyn Matcher + Sync),
145 matcher: &'a (dyn Matcher + Sync),
146 root_dir: PathBuf,
146 root_dir: PathBuf,
147 ignore_files: Vec<PathBuf>,
147 ignore_files: Vec<PathBuf>,
148 options: StatusOptions,
148 options: StatusOptions,
149 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
149 ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>
150 {
150 {
151 self.get_mut()
151 self.get_mut()
152 .status(matcher, root_dir, ignore_files, options)
152 .status(matcher, root_dir, ignore_files, options)
153 }
153 }
154
154
155 fn copy_map_len(&self) -> usize {
155 fn copy_map_len(&self) -> usize {
156 self.get().copy_map_len()
156 self.get().copy_map_len()
157 }
157 }
158
158
159 fn copy_map_iter(&self) -> CopyMapIter<'_> {
159 fn copy_map_iter(&self) -> CopyMapIter<'_> {
160 self.get().copy_map_iter()
160 self.get().copy_map_iter()
161 }
161 }
162
162
163 fn copy_map_contains_key(
163 fn copy_map_contains_key(
164 &self,
164 &self,
165 key: &HgPath,
165 key: &HgPath,
166 ) -> Result<bool, DirstateV2ParseError> {
166 ) -> Result<bool, DirstateV2ParseError> {
167 self.get().copy_map_contains_key(key)
167 self.get().copy_map_contains_key(key)
168 }
168 }
169
169
170 fn copy_map_get(
170 fn copy_map_get(
171 &self,
171 &self,
172 key: &HgPath,
172 key: &HgPath,
173 ) -> Result<Option<&HgPath>, DirstateV2ParseError> {
173 ) -> Result<Option<&HgPath>, DirstateV2ParseError> {
174 self.get().copy_map_get(key)
174 self.get().copy_map_get(key)
175 }
175 }
176
176
177 fn copy_map_remove(
177 fn copy_map_remove(
178 &mut self,
178 &mut self,
179 key: &HgPath,
179 key: &HgPath,
180 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
180 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
181 self.get_mut().copy_map_remove(key)
181 self.get_mut().copy_map_remove(key)
182 }
182 }
183
183
184 fn copy_map_insert(
184 fn copy_map_insert(
185 &mut self,
185 &mut self,
186 key: HgPathBuf,
186 key: HgPathBuf,
187 value: HgPathBuf,
187 value: HgPathBuf,
188 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
188 ) -> Result<Option<HgPathBuf>, DirstateV2ParseError> {
189 self.get_mut().copy_map_insert(key, value)
189 self.get_mut().copy_map_insert(key, value)
190 }
190 }
191
191
192 fn len(&self) -> usize {
192 fn len(&self) -> usize {
193 self.get().len()
193 self.get().len()
194 }
194 }
195
195
196 fn contains_key(
196 fn contains_key(
197 &self,
197 &self,
198 key: &HgPath,
198 key: &HgPath,
199 ) -> Result<bool, DirstateV2ParseError> {
199 ) -> Result<bool, DirstateV2ParseError> {
200 self.get().contains_key(key)
200 self.get().contains_key(key)
201 }
201 }
202
202
203 fn get(
203 fn get(
204 &self,
204 &self,
205 key: &HgPath,
205 key: &HgPath,
206 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
206 ) -> Result<Option<DirstateEntry>, DirstateV2ParseError> {
207 self.get().get(key)
207 self.get().get(key)
208 }
208 }
209
209
210 fn iter(&self) -> StateMapIter<'_> {
210 fn iter(&self) -> StateMapIter<'_> {
211 self.get().iter()
211 self.get().iter()
212 }
212 }
213
213
214 fn iter_tracked_dirs(
214 fn iter_tracked_dirs(
215 &mut self,
215 &mut self,
216 ) -> Result<
216 ) -> Result<
217 Box<
217 Box<
218 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>>
218 dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>>
219 + Send
219 + Send
220 + '_,
220 + '_,
221 >,
221 >,
222 DirstateError,
222 DirstateError,
223 > {
223 > {
224 self.get_mut().iter_tracked_dirs()
224 self.get_mut().iter_tracked_dirs()
225 }
225 }
226
226
227 fn debug_iter(
227 fn debug_iter(
228 &self,
228 &self,
229 ) -> Box<
229 ) -> Box<
230 dyn Iterator<
230 dyn Iterator<
231 Item = Result<
231 Item = Result<
232 (&HgPath, (u8, i32, i32, i32)),
232 (&HgPath, (u8, i32, i32, i32)),
233 DirstateV2ParseError,
233 DirstateV2ParseError,
234 >,
234 >,
235 > + Send
235 > + Send
236 + '_,
236 + '_,
237 > {
237 > {
238 self.get().debug_iter()
238 self.get().debug_iter()
239 }
239 }
240 }
240 }
@@ -1,32 +1,33 b''
1 [package]
1 [package]
2 name = "hg-cpython"
2 name = "hg-cpython"
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 edition = "2018"
5 edition = "2018"
6
6
7 [lib]
7 [lib]
8 name='rusthg'
8 name='rusthg'
9 crate-type = ["cdylib"]
9 crate-type = ["cdylib"]
10
10
11 [features]
11 [features]
12 default = ["python27"]
12 default = ["python27"]
13
13
14 # Features to build an extension module:
14 # Features to build an extension module:
15 python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
15 python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
16 python3 = ["cpython/python3-sys", "cpython/extension-module"]
16 python3 = ["cpython/python3-sys", "cpython/extension-module"]
17
17
18 # Enable one of these features to build a test executable linked to libpython:
18 # Enable one of these features to build a test executable linked to libpython:
19 # e.g. cargo test --no-default-features --features python27-bin
19 # e.g. cargo test --no-default-features --features python27-bin
20 python27-bin = ["cpython/python27-sys"]
20 python27-bin = ["cpython/python27-sys"]
21 python3-bin = ["cpython/python3-sys"]
21 python3-bin = ["cpython/python3-sys"]
22
22
23 [dependencies]
23 [dependencies]
24 crossbeam-channel = "0.4"
24 crossbeam-channel = "0.4"
25 hg-core = { path = "../hg-core"}
25 hg-core = { path = "../hg-core"}
26 libc = '*'
26 libc = '*'
27 log = "0.4.8"
27 log = "0.4.8"
28 env_logger = "0.7.1"
28 env_logger = "0.7.1"
29 stable_deref_trait = "1.2.0"
29
30
30 [dependencies.cpython]
31 [dependencies.cpython]
31 version = "0.6.0"
32 version = "0.6.0"
32 default-features = false
33 default-features = false
@@ -1,154 +1,152 b''
1 // dirstate.rs
1 // dirstate.rs
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 //! Bindings for the `hg::dirstate` module provided by the
8 //! Bindings for the `hg::dirstate` module provided by the
9 //! `hg-core` package.
9 //! `hg-core` package.
10 //!
10 //!
11 //! From Python, this will be seen as `mercurial.rustext.dirstate`
11 //! From Python, this will be seen as `mercurial.rustext.dirstate`
12 mod copymap;
12 mod copymap;
13 mod dirs_multiset;
13 mod dirs_multiset;
14 mod dirstate_map;
14 mod dirstate_map;
15 mod dispatch;
16 mod non_normal_entries;
15 mod non_normal_entries;
17 mod owning;
18 mod status;
16 mod status;
19 use crate::{
17 use crate::{
20 dirstate::{
18 dirstate::{
21 dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
19 dirs_multiset::Dirs, dirstate_map::DirstateMap, status::status_wrapper,
22 },
20 },
23 exceptions,
21 exceptions,
24 };
22 };
25 use cpython::{
23 use cpython::{
26 exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult,
24 exc, PyBytes, PyDict, PyErr, PyList, PyModule, PyObject, PyResult,
27 PySequence, Python,
25 PySequence, Python,
28 };
26 };
29 use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER;
27 use hg::dirstate_tree::on_disk::V2_FORMAT_MARKER;
30 use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap};
28 use hg::{utils::hg_path::HgPathBuf, DirstateEntry, EntryState, StateMap};
31 use libc::{c_char, c_int};
29 use libc::{c_char, c_int};
32 use std::convert::TryFrom;
30 use std::convert::TryFrom;
33
31
34 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
32 // C code uses a custom `dirstate_tuple` type, checks in multiple instances
35 // for this type, and raises a Python `Exception` if the check does not pass.
33 // for this type, and raises a Python `Exception` if the check does not pass.
36 // Because this type differs only in name from the regular Python tuple, it
34 // Because this type differs only in name from the regular Python tuple, it
37 // would be a good idea in the near future to remove it entirely to allow
35 // would be a good idea in the near future to remove it entirely to allow
38 // for a pure Python tuple of the same effective structure to be used,
36 // for a pure Python tuple of the same effective structure to be used,
39 // rendering this type and the capsule below useless.
37 // rendering this type and the capsule below useless.
40 py_capsule_fn!(
38 py_capsule_fn!(
41 from mercurial.cext.parsers import make_dirstate_item_CAPI
39 from mercurial.cext.parsers import make_dirstate_item_CAPI
42 as make_dirstate_item_capi
40 as make_dirstate_item_capi
43 signature (
41 signature (
44 state: c_char,
42 state: c_char,
45 mode: c_int,
43 mode: c_int,
46 size: c_int,
44 size: c_int,
47 mtime: c_int,
45 mtime: c_int,
48 ) -> *mut RawPyObject
46 ) -> *mut RawPyObject
49 );
47 );
50
48
51 pub fn make_dirstate_item(
49 pub fn make_dirstate_item(
52 py: Python,
50 py: Python,
53 entry: &DirstateEntry,
51 entry: &DirstateEntry,
54 ) -> PyResult<PyObject> {
52 ) -> PyResult<PyObject> {
55 let &DirstateEntry {
53 let &DirstateEntry {
56 state,
54 state,
57 mode,
55 mode,
58 size,
56 size,
59 mtime,
57 mtime,
60 } = entry;
58 } = entry;
61 // Explicitly go through u8 first, then cast to platform-specific `c_char`
59 // Explicitly go through u8 first, then cast to platform-specific `c_char`
62 // because Into<u8> has a specific implementation while `as c_char` would
60 // because Into<u8> has a specific implementation while `as c_char` would
63 // just do a naive enum cast.
61 // just do a naive enum cast.
64 let state_code: u8 = state.into();
62 let state_code: u8 = state.into();
65 make_dirstate_item_raw(py, state_code, mode, size, mtime)
63 make_dirstate_item_raw(py, state_code, mode, size, mtime)
66 }
64 }
67
65
68 pub fn make_dirstate_item_raw(
66 pub fn make_dirstate_item_raw(
69 py: Python,
67 py: Python,
70 state: u8,
68 state: u8,
71 mode: i32,
69 mode: i32,
72 size: i32,
70 size: i32,
73 mtime: i32,
71 mtime: i32,
74 ) -> PyResult<PyObject> {
72 ) -> PyResult<PyObject> {
75 let make = make_dirstate_item_capi::retrieve(py)?;
73 let make = make_dirstate_item_capi::retrieve(py)?;
76 let maybe_obj = unsafe {
74 let maybe_obj = unsafe {
77 let ptr = make(state as c_char, mode, size, mtime);
75 let ptr = make(state as c_char, mode, size, mtime);
78 PyObject::from_owned_ptr_opt(py, ptr)
76 PyObject::from_owned_ptr_opt(py, ptr)
79 };
77 };
80 maybe_obj.ok_or_else(|| PyErr::fetch(py))
78 maybe_obj.ok_or_else(|| PyErr::fetch(py))
81 }
79 }
82
80
83 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
81 pub fn extract_dirstate(py: Python, dmap: &PyDict) -> Result<StateMap, PyErr> {
84 dmap.items(py)
82 dmap.items(py)
85 .iter()
83 .iter()
86 .map(|(filename, stats)| {
84 .map(|(filename, stats)| {
87 let stats = stats.extract::<PySequence>(py)?;
85 let stats = stats.extract::<PySequence>(py)?;
88 let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
86 let state = stats.get_item(py, 0)?.extract::<PyBytes>(py)?;
89 let state =
87 let state =
90 EntryState::try_from(state.data(py)[0]).map_err(|e| {
88 EntryState::try_from(state.data(py)[0]).map_err(|e| {
91 PyErr::new::<exc::ValueError, _>(py, e.to_string())
89 PyErr::new::<exc::ValueError, _>(py, e.to_string())
92 })?;
90 })?;
93 let mode = stats.get_item(py, 1)?.extract(py)?;
91 let mode = stats.get_item(py, 1)?.extract(py)?;
94 let size = stats.get_item(py, 2)?.extract(py)?;
92 let size = stats.get_item(py, 2)?.extract(py)?;
95 let mtime = stats.get_item(py, 3)?.extract(py)?;
93 let mtime = stats.get_item(py, 3)?.extract(py)?;
96 let filename = filename.extract::<PyBytes>(py)?;
94 let filename = filename.extract::<PyBytes>(py)?;
97 let filename = filename.data(py);
95 let filename = filename.data(py);
98 Ok((
96 Ok((
99 HgPathBuf::from(filename.to_owned()),
97 HgPathBuf::from(filename.to_owned()),
100 DirstateEntry {
98 DirstateEntry {
101 state,
99 state,
102 mode,
100 mode,
103 size,
101 size,
104 mtime,
102 mtime,
105 },
103 },
106 ))
104 ))
107 })
105 })
108 .collect()
106 .collect()
109 }
107 }
110
108
111 /// Create the module, with `__package__` given from parent
109 /// Create the module, with `__package__` given from parent
112 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
110 pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
113 let dotted_name = &format!("{}.dirstate", package);
111 let dotted_name = &format!("{}.dirstate", package);
114 let m = PyModule::new(py, dotted_name)?;
112 let m = PyModule::new(py, dotted_name)?;
115
113
116 env_logger::init();
114 env_logger::init();
117
115
118 m.add(py, "__package__", package)?;
116 m.add(py, "__package__", package)?;
119 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
117 m.add(py, "__doc__", "Dirstate - Rust implementation")?;
120
118
121 m.add(
119 m.add(
122 py,
120 py,
123 "FallbackError",
121 "FallbackError",
124 py.get_type::<exceptions::FallbackError>(),
122 py.get_type::<exceptions::FallbackError>(),
125 )?;
123 )?;
126 m.add_class::<Dirs>(py)?;
124 m.add_class::<Dirs>(py)?;
127 m.add_class::<DirstateMap>(py)?;
125 m.add_class::<DirstateMap>(py)?;
128 m.add(py, "V2_FORMAT_MARKER", PyBytes::new(py, V2_FORMAT_MARKER))?;
126 m.add(py, "V2_FORMAT_MARKER", PyBytes::new(py, V2_FORMAT_MARKER))?;
129 m.add(
127 m.add(
130 py,
128 py,
131 "status",
129 "status",
132 py_fn!(
130 py_fn!(
133 py,
131 py,
134 status_wrapper(
132 status_wrapper(
135 dmap: DirstateMap,
133 dmap: DirstateMap,
136 root_dir: PyObject,
134 root_dir: PyObject,
137 matcher: PyObject,
135 matcher: PyObject,
138 ignorefiles: PyList,
136 ignorefiles: PyList,
139 check_exec: bool,
137 check_exec: bool,
140 last_normal_time: i64,
138 last_normal_time: i64,
141 list_clean: bool,
139 list_clean: bool,
142 list_ignored: bool,
140 list_ignored: bool,
143 list_unknown: bool,
141 list_unknown: bool,
144 collect_traversed_dirs: bool
142 collect_traversed_dirs: bool
145 )
143 )
146 ),
144 ),
147 )?;
145 )?;
148
146
149 let sys = PyModule::import(py, "sys")?;
147 let sys = PyModule::import(py, "sys")?;
150 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
148 let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
151 sys_modules.set_item(py, dotted_name, &m)?;
149 sys_modules.set_item(py, dotted_name, &m)?;
152
150
153 Ok(m)
151 Ok(m)
154 }
152 }
@@ -1,669 +1,679 b''
1 // dirstate_map.rs
1 // dirstate_map.rs
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 //! Bindings for the `hg::dirstate::dirstate_map` file provided by the
8 //! Bindings for the `hg::dirstate::dirstate_map` file provided by the
9 //! `hg-core` package.
9 //! `hg-core` package.
10
10
11 use std::cell::{RefCell, RefMut};
11 use std::cell::{RefCell, RefMut};
12 use std::convert::TryInto;
12 use std::convert::TryInto;
13
13
14 use cpython::{
14 use cpython::{
15 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList,
15 exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList,
16 PyObject, PyResult, PySet, PyString, Python, PythonObject, ToPyObject,
16 PyObject, PyResult, PySet, PyString, Python, PythonObject, ToPyObject,
17 UnsafePyLeaked,
17 UnsafePyLeaked,
18 };
18 };
19
19
20 use crate::{
20 use crate::{
21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
21 dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
22 dirstate::make_dirstate_item,
22 dirstate::make_dirstate_item,
23 dirstate::make_dirstate_item_raw,
23 dirstate::make_dirstate_item_raw,
24 dirstate::non_normal_entries::{
24 dirstate::non_normal_entries::{
25 NonNormalEntries, NonNormalEntriesIterator,
25 NonNormalEntries, NonNormalEntriesIterator,
26 },
26 },
27 dirstate::owning::OwningDirstateMap,
28 parsers::dirstate_parents_to_pytuple,
27 parsers::dirstate_parents_to_pytuple,
28 pybytes_deref::PyBytesDeref,
29 };
29 };
30 use hg::{
30 use hg::{
31 dirstate::parsers::Timestamp,
31 dirstate::parsers::Timestamp,
32 dirstate::MTIME_UNSET,
32 dirstate::MTIME_UNSET,
33 dirstate::SIZE_NON_NORMAL,
33 dirstate::SIZE_NON_NORMAL,
34 dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap,
34 dirstate_tree::dispatch::DirstateMapMethods,
35 dirstate_tree::dispatch::DirstateMapMethods,
35 dirstate_tree::on_disk::DirstateV2ParseError,
36 dirstate_tree::on_disk::DirstateV2ParseError,
37 dirstate_tree::owning::OwningDirstateMap,
36 revlog::Node,
38 revlog::Node,
37 utils::files::normalize_case,
39 utils::files::normalize_case,
38 utils::hg_path::{HgPath, HgPathBuf},
40 utils::hg_path::{HgPath, HgPathBuf},
39 DirstateEntry, DirstateError, DirstateMap as RustDirstateMap,
41 DirstateEntry, DirstateError, DirstateMap as RustDirstateMap,
40 DirstateParents, EntryState, StateMapIter,
42 DirstateParents, EntryState, StateMapIter,
41 };
43 };
42
44
43 // TODO
45 // TODO
44 // This object needs to share references to multiple members of its Rust
46 // This object needs to share references to multiple members of its Rust
45 // inner struct, namely `copy_map`, `dirs` and `all_dirs`.
47 // inner struct, namely `copy_map`, `dirs` and `all_dirs`.
46 // Right now `CopyMap` is done, but it needs to have an explicit reference
48 // Right now `CopyMap` is done, but it needs to have an explicit reference
47 // to `RustDirstateMap` which itself needs to have an encapsulation for
49 // to `RustDirstateMap` which itself needs to have an encapsulation for
48 // every method in `CopyMap` (copymapcopy, etc.).
50 // every method in `CopyMap` (copymapcopy, etc.).
49 // This is ugly and hard to maintain.
51 // This is ugly and hard to maintain.
50 // The same logic applies to `dirs` and `all_dirs`, however the `Dirs`
52 // The same logic applies to `dirs` and `all_dirs`, however the `Dirs`
51 // `py_class!` is already implemented and does not mention
53 // `py_class!` is already implemented and does not mention
52 // `RustDirstateMap`, rightfully so.
54 // `RustDirstateMap`, rightfully so.
53 // All attributes also have to have a separate refcount data attribute for
55 // All attributes also have to have a separate refcount data attribute for
54 // leaks, with all methods that go along for reference sharing.
56 // leaks, with all methods that go along for reference sharing.
55 py_class!(pub class DirstateMap |py| {
57 py_class!(pub class DirstateMap |py| {
56 @shared data inner: Box<dyn DirstateMapMethods + Send>;
58 @shared data inner: Box<dyn DirstateMapMethods + Send>;
57
59
58 /// Returns a `(dirstate_map, parents)` tuple
60 /// Returns a `(dirstate_map, parents)` tuple
59 @staticmethod
61 @staticmethod
60 def new_v1(
62 def new_v1(
61 use_dirstate_tree: bool,
63 use_dirstate_tree: bool,
62 on_disk: PyBytes,
64 on_disk: PyBytes,
63 ) -> PyResult<PyObject> {
65 ) -> PyResult<PyObject> {
64 let (inner, parents) = if use_dirstate_tree {
66 let (inner, parents) = if use_dirstate_tree {
65 let (map, parents) = OwningDirstateMap::new_v1(py, on_disk)
67 let on_disk = PyBytesDeref::new(py, on_disk);
68 let mut map = OwningDirstateMap::new_empty(on_disk);
69 let (on_disk, map_placeholder) = map.get_mut_pair();
70
71 let (actual_map, parents) = TreeDirstateMap::new_v1(on_disk)
66 .map_err(|e| dirstate_error(py, e))?;
72 .map_err(|e| dirstate_error(py, e))?;
73 *map_placeholder = actual_map;
67 (Box::new(map) as _, parents)
74 (Box::new(map) as _, parents)
68 } else {
75 } else {
69 let bytes = on_disk.data(py);
76 let bytes = on_disk.data(py);
70 let mut map = RustDirstateMap::default();
77 let mut map = RustDirstateMap::default();
71 let parents = map.read(bytes).map_err(|e| dirstate_error(py, e))?;
78 let parents = map.read(bytes).map_err(|e| dirstate_error(py, e))?;
72 (Box::new(map) as _, parents)
79 (Box::new(map) as _, parents)
73 };
80 };
74 let map = Self::create_instance(py, inner)?;
81 let map = Self::create_instance(py, inner)?;
75 let parents = parents.map(|p| dirstate_parents_to_pytuple(py, &p));
82 let parents = parents.map(|p| dirstate_parents_to_pytuple(py, &p));
76 Ok((map, parents).to_py_object(py).into_object())
83 Ok((map, parents).to_py_object(py).into_object())
77 }
84 }
78
85
79 /// Returns a DirstateMap
86 /// Returns a DirstateMap
80 @staticmethod
87 @staticmethod
81 def new_v2(
88 def new_v2(
82 on_disk: PyBytes,
89 on_disk: PyBytes,
83 data_size: usize,
90 data_size: usize,
84 tree_metadata: PyBytes,
91 tree_metadata: PyBytes,
85 ) -> PyResult<PyObject> {
92 ) -> PyResult<PyObject> {
86 let dirstate_error = |e: DirstateError| {
93 let dirstate_error = |e: DirstateError| {
87 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
94 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
88 };
95 };
89 let inner = OwningDirstateMap::new_v2(
96 let on_disk = PyBytesDeref::new(py, on_disk);
90 py, on_disk, data_size, tree_metadata,
97 let mut map = OwningDirstateMap::new_empty(on_disk);
98 let (on_disk, map_placeholder) = map.get_mut_pair();
99 *map_placeholder = TreeDirstateMap::new_v2(
100 on_disk, data_size, tree_metadata.data(py),
91 ).map_err(dirstate_error)?;
101 ).map_err(dirstate_error)?;
92 let map = Self::create_instance(py, Box::new(inner))?;
102 let map = Self::create_instance(py, Box::new(map))?;
93 Ok(map.into_object())
103 Ok(map.into_object())
94 }
104 }
95
105
96 def clear(&self) -> PyResult<PyObject> {
106 def clear(&self) -> PyResult<PyObject> {
97 self.inner(py).borrow_mut().clear();
107 self.inner(py).borrow_mut().clear();
98 Ok(py.None())
108 Ok(py.None())
99 }
109 }
100
110
101 def get(
111 def get(
102 &self,
112 &self,
103 key: PyObject,
113 key: PyObject,
104 default: Option<PyObject> = None
114 default: Option<PyObject> = None
105 ) -> PyResult<Option<PyObject>> {
115 ) -> PyResult<Option<PyObject>> {
106 let key = key.extract::<PyBytes>(py)?;
116 let key = key.extract::<PyBytes>(py)?;
107 match self
117 match self
108 .inner(py)
118 .inner(py)
109 .borrow()
119 .borrow()
110 .get(HgPath::new(key.data(py)))
120 .get(HgPath::new(key.data(py)))
111 .map_err(|e| v2_error(py, e))?
121 .map_err(|e| v2_error(py, e))?
112 {
122 {
113 Some(entry) => {
123 Some(entry) => {
114 Ok(Some(make_dirstate_item(py, &entry)?))
124 Ok(Some(make_dirstate_item(py, &entry)?))
115 },
125 },
116 None => Ok(default)
126 None => Ok(default)
117 }
127 }
118 }
128 }
119
129
120 def set_v1(&self, path: PyObject, item: PyObject) -> PyResult<PyObject> {
130 def set_v1(&self, path: PyObject, item: PyObject) -> PyResult<PyObject> {
121 let f = path.extract::<PyBytes>(py)?;
131 let f = path.extract::<PyBytes>(py)?;
122 let filename = HgPath::new(f.data(py));
132 let filename = HgPath::new(f.data(py));
123 let state = item.getattr(py, "state")?.extract::<PyBytes>(py)?;
133 let state = item.getattr(py, "state")?.extract::<PyBytes>(py)?;
124 let state = state.data(py)[0];
134 let state = state.data(py)[0];
125 let entry = DirstateEntry {
135 let entry = DirstateEntry {
126 state: state.try_into().expect("state is always valid"),
136 state: state.try_into().expect("state is always valid"),
127 mtime: item.getattr(py, "mtime")?.extract(py)?,
137 mtime: item.getattr(py, "mtime")?.extract(py)?,
128 size: item.getattr(py, "size")?.extract(py)?,
138 size: item.getattr(py, "size")?.extract(py)?,
129 mode: item.getattr(py, "mode")?.extract(py)?,
139 mode: item.getattr(py, "mode")?.extract(py)?,
130 };
140 };
131 self.inner(py).borrow_mut().set_v1(filename, entry);
141 self.inner(py).borrow_mut().set_v1(filename, entry);
132 Ok(py.None())
142 Ok(py.None())
133 }
143 }
134
144
135 def addfile(
145 def addfile(
136 &self,
146 &self,
137 f: PyObject,
147 f: PyObject,
138 mode: PyObject,
148 mode: PyObject,
139 size: PyObject,
149 size: PyObject,
140 mtime: PyObject,
150 mtime: PyObject,
141 added: PyObject,
151 added: PyObject,
142 merged: PyObject,
152 merged: PyObject,
143 from_p2: PyObject,
153 from_p2: PyObject,
144 possibly_dirty: PyObject,
154 possibly_dirty: PyObject,
145 ) -> PyResult<PyObject> {
155 ) -> PyResult<PyObject> {
146 let f = f.extract::<PyBytes>(py)?;
156 let f = f.extract::<PyBytes>(py)?;
147 let filename = HgPath::new(f.data(py));
157 let filename = HgPath::new(f.data(py));
148 let mode = if mode.is_none(py) {
158 let mode = if mode.is_none(py) {
149 // fallback default value
159 // fallback default value
150 0
160 0
151 } else {
161 } else {
152 mode.extract(py)?
162 mode.extract(py)?
153 };
163 };
154 let size = if size.is_none(py) {
164 let size = if size.is_none(py) {
155 // fallback default value
165 // fallback default value
156 SIZE_NON_NORMAL
166 SIZE_NON_NORMAL
157 } else {
167 } else {
158 size.extract(py)?
168 size.extract(py)?
159 };
169 };
160 let mtime = if mtime.is_none(py) {
170 let mtime = if mtime.is_none(py) {
161 // fallback default value
171 // fallback default value
162 MTIME_UNSET
172 MTIME_UNSET
163 } else {
173 } else {
164 mtime.extract(py)?
174 mtime.extract(py)?
165 };
175 };
166 let entry = DirstateEntry {
176 let entry = DirstateEntry {
167 // XXX Arbitrary default value since the value is determined later
177 // XXX Arbitrary default value since the value is determined later
168 state: EntryState::Normal,
178 state: EntryState::Normal,
169 mode: mode,
179 mode: mode,
170 size: size,
180 size: size,
171 mtime: mtime,
181 mtime: mtime,
172 };
182 };
173 let added = added.extract::<PyBool>(py)?.is_true();
183 let added = added.extract::<PyBool>(py)?.is_true();
174 let merged = merged.extract::<PyBool>(py)?.is_true();
184 let merged = merged.extract::<PyBool>(py)?.is_true();
175 let from_p2 = from_p2.extract::<PyBool>(py)?.is_true();
185 let from_p2 = from_p2.extract::<PyBool>(py)?.is_true();
176 let possibly_dirty = possibly_dirty.extract::<PyBool>(py)?.is_true();
186 let possibly_dirty = possibly_dirty.extract::<PyBool>(py)?.is_true();
177 self.inner(py).borrow_mut().add_file(
187 self.inner(py).borrow_mut().add_file(
178 filename,
188 filename,
179 entry,
189 entry,
180 added,
190 added,
181 merged,
191 merged,
182 from_p2,
192 from_p2,
183 possibly_dirty
193 possibly_dirty
184 ).and(Ok(py.None())).or_else(|e: DirstateError| {
194 ).and(Ok(py.None())).or_else(|e: DirstateError| {
185 Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
195 Err(PyErr::new::<exc::ValueError, _>(py, e.to_string()))
186 })
196 })
187 }
197 }
188
198
189 def removefile(
199 def removefile(
190 &self,
200 &self,
191 f: PyObject,
201 f: PyObject,
192 in_merge: PyObject
202 in_merge: PyObject
193 ) -> PyResult<PyObject> {
203 ) -> PyResult<PyObject> {
194 self.inner(py).borrow_mut()
204 self.inner(py).borrow_mut()
195 .remove_file(
205 .remove_file(
196 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
206 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
197 in_merge.extract::<PyBool>(py)?.is_true(),
207 in_merge.extract::<PyBool>(py)?.is_true(),
198 )
208 )
199 .or_else(|_| {
209 .or_else(|_| {
200 Err(PyErr::new::<exc::OSError, _>(
210 Err(PyErr::new::<exc::OSError, _>(
201 py,
211 py,
202 "Dirstate error".to_string(),
212 "Dirstate error".to_string(),
203 ))
213 ))
204 })?;
214 })?;
205 Ok(py.None())
215 Ok(py.None())
206 }
216 }
207
217
208 def dropfile(
218 def dropfile(
209 &self,
219 &self,
210 f: PyObject,
220 f: PyObject,
211 ) -> PyResult<PyBool> {
221 ) -> PyResult<PyBool> {
212 self.inner(py).borrow_mut()
222 self.inner(py).borrow_mut()
213 .drop_file(
223 .drop_file(
214 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
224 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
215 )
225 )
216 .and_then(|b| Ok(b.to_py_object(py)))
226 .and_then(|b| Ok(b.to_py_object(py)))
217 .or_else(|e| {
227 .or_else(|e| {
218 Err(PyErr::new::<exc::OSError, _>(
228 Err(PyErr::new::<exc::OSError, _>(
219 py,
229 py,
220 format!("Dirstate error: {}", e.to_string()),
230 format!("Dirstate error: {}", e.to_string()),
221 ))
231 ))
222 })
232 })
223 }
233 }
224
234
225 def clearambiguoustimes(
235 def clearambiguoustimes(
226 &self,
236 &self,
227 files: PyObject,
237 files: PyObject,
228 now: PyObject
238 now: PyObject
229 ) -> PyResult<PyObject> {
239 ) -> PyResult<PyObject> {
230 let files: PyResult<Vec<HgPathBuf>> = files
240 let files: PyResult<Vec<HgPathBuf>> = files
231 .iter(py)?
241 .iter(py)?
232 .map(|filename| {
242 .map(|filename| {
233 Ok(HgPathBuf::from_bytes(
243 Ok(HgPathBuf::from_bytes(
234 filename?.extract::<PyBytes>(py)?.data(py),
244 filename?.extract::<PyBytes>(py)?.data(py),
235 ))
245 ))
236 })
246 })
237 .collect();
247 .collect();
238 self.inner(py)
248 self.inner(py)
239 .borrow_mut()
249 .borrow_mut()
240 .clear_ambiguous_times(files?, now.extract(py)?)
250 .clear_ambiguous_times(files?, now.extract(py)?)
241 .map_err(|e| v2_error(py, e))?;
251 .map_err(|e| v2_error(py, e))?;
242 Ok(py.None())
252 Ok(py.None())
243 }
253 }
244
254
245 def other_parent_entries(&self) -> PyResult<PyObject> {
255 def other_parent_entries(&self) -> PyResult<PyObject> {
246 let mut inner_shared = self.inner(py).borrow_mut();
256 let mut inner_shared = self.inner(py).borrow_mut();
247 let set = PySet::empty(py)?;
257 let set = PySet::empty(py)?;
248 for path in inner_shared.iter_other_parent_paths() {
258 for path in inner_shared.iter_other_parent_paths() {
249 let path = path.map_err(|e| v2_error(py, e))?;
259 let path = path.map_err(|e| v2_error(py, e))?;
250 set.add(py, PyBytes::new(py, path.as_bytes()))?;
260 set.add(py, PyBytes::new(py, path.as_bytes()))?;
251 }
261 }
252 Ok(set.into_object())
262 Ok(set.into_object())
253 }
263 }
254
264
255 def non_normal_entries(&self) -> PyResult<NonNormalEntries> {
265 def non_normal_entries(&self) -> PyResult<NonNormalEntries> {
256 NonNormalEntries::from_inner(py, self.clone_ref(py))
266 NonNormalEntries::from_inner(py, self.clone_ref(py))
257 }
267 }
258
268
259 def non_normal_entries_contains(&self, key: PyObject) -> PyResult<bool> {
269 def non_normal_entries_contains(&self, key: PyObject) -> PyResult<bool> {
260 let key = key.extract::<PyBytes>(py)?;
270 let key = key.extract::<PyBytes>(py)?;
261 self.inner(py)
271 self.inner(py)
262 .borrow_mut()
272 .borrow_mut()
263 .non_normal_entries_contains(HgPath::new(key.data(py)))
273 .non_normal_entries_contains(HgPath::new(key.data(py)))
264 .map_err(|e| v2_error(py, e))
274 .map_err(|e| v2_error(py, e))
265 }
275 }
266
276
267 def non_normal_entries_display(&self) -> PyResult<PyString> {
277 def non_normal_entries_display(&self) -> PyResult<PyString> {
268 let mut inner = self.inner(py).borrow_mut();
278 let mut inner = self.inner(py).borrow_mut();
269 let paths = inner
279 let paths = inner
270 .iter_non_normal_paths()
280 .iter_non_normal_paths()
271 .collect::<Result<Vec<_>, _>>()
281 .collect::<Result<Vec<_>, _>>()
272 .map_err(|e| v2_error(py, e))?;
282 .map_err(|e| v2_error(py, e))?;
273 let formatted = format!("NonNormalEntries: {}", hg::utils::join_display(paths, ", "));
283 let formatted = format!("NonNormalEntries: {}", hg::utils::join_display(paths, ", "));
274 Ok(PyString::new(py, &formatted))
284 Ok(PyString::new(py, &formatted))
275 }
285 }
276
286
277 def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> {
287 def non_normal_entries_remove(&self, key: PyObject) -> PyResult<PyObject> {
278 let key = key.extract::<PyBytes>(py)?;
288 let key = key.extract::<PyBytes>(py)?;
279 let key = key.data(py);
289 let key = key.data(py);
280 let was_present = self
290 let was_present = self
281 .inner(py)
291 .inner(py)
282 .borrow_mut()
292 .borrow_mut()
283 .non_normal_entries_remove(HgPath::new(key));
293 .non_normal_entries_remove(HgPath::new(key));
284 if !was_present {
294 if !was_present {
285 let msg = String::from_utf8_lossy(key);
295 let msg = String::from_utf8_lossy(key);
286 Err(PyErr::new::<exc::KeyError, _>(py, msg))
296 Err(PyErr::new::<exc::KeyError, _>(py, msg))
287 } else {
297 } else {
288 Ok(py.None())
298 Ok(py.None())
289 }
299 }
290 }
300 }
291
301
292 def non_normal_entries_discard(&self, key: PyObject) -> PyResult<PyObject>
302 def non_normal_entries_discard(&self, key: PyObject) -> PyResult<PyObject>
293 {
303 {
294 let key = key.extract::<PyBytes>(py)?;
304 let key = key.extract::<PyBytes>(py)?;
295 self
305 self
296 .inner(py)
306 .inner(py)
297 .borrow_mut()
307 .borrow_mut()
298 .non_normal_entries_remove(HgPath::new(key.data(py)));
308 .non_normal_entries_remove(HgPath::new(key.data(py)));
299 Ok(py.None())
309 Ok(py.None())
300 }
310 }
301
311
302 def non_normal_entries_add(&self, key: PyObject) -> PyResult<PyObject> {
312 def non_normal_entries_add(&self, key: PyObject) -> PyResult<PyObject> {
303 let key = key.extract::<PyBytes>(py)?;
313 let key = key.extract::<PyBytes>(py)?;
304 self
314 self
305 .inner(py)
315 .inner(py)
306 .borrow_mut()
316 .borrow_mut()
307 .non_normal_entries_add(HgPath::new(key.data(py)));
317 .non_normal_entries_add(HgPath::new(key.data(py)));
308 Ok(py.None())
318 Ok(py.None())
309 }
319 }
310
320
311 def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> {
321 def non_normal_or_other_parent_paths(&self) -> PyResult<PyList> {
312 let mut inner = self.inner(py).borrow_mut();
322 let mut inner = self.inner(py).borrow_mut();
313
323
314 let ret = PyList::new(py, &[]);
324 let ret = PyList::new(py, &[]);
315 for filename in inner.non_normal_or_other_parent_paths() {
325 for filename in inner.non_normal_or_other_parent_paths() {
316 let filename = filename.map_err(|e| v2_error(py, e))?;
326 let filename = filename.map_err(|e| v2_error(py, e))?;
317 let as_pystring = PyBytes::new(py, filename.as_bytes());
327 let as_pystring = PyBytes::new(py, filename.as_bytes());
318 ret.append(py, as_pystring.into_object());
328 ret.append(py, as_pystring.into_object());
319 }
329 }
320 Ok(ret)
330 Ok(ret)
321 }
331 }
322
332
323 def non_normal_entries_iter(&self) -> PyResult<NonNormalEntriesIterator> {
333 def non_normal_entries_iter(&self) -> PyResult<NonNormalEntriesIterator> {
324 // Make sure the sets are defined before we no longer have a mutable
334 // Make sure the sets are defined before we no longer have a mutable
325 // reference to the dmap.
335 // reference to the dmap.
326 self.inner(py)
336 self.inner(py)
327 .borrow_mut()
337 .borrow_mut()
328 .set_non_normal_other_parent_entries(false);
338 .set_non_normal_other_parent_entries(false);
329
339
330 let leaked_ref = self.inner(py).leak_immutable();
340 let leaked_ref = self.inner(py).leak_immutable();
331
341
332 NonNormalEntriesIterator::from_inner(py, unsafe {
342 NonNormalEntriesIterator::from_inner(py, unsafe {
333 leaked_ref.map(py, |o| {
343 leaked_ref.map(py, |o| {
334 o.iter_non_normal_paths_panic()
344 o.iter_non_normal_paths_panic()
335 })
345 })
336 })
346 })
337 }
347 }
338
348
339 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
349 def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
340 let d = d.extract::<PyBytes>(py)?;
350 let d = d.extract::<PyBytes>(py)?;
341 Ok(self.inner(py).borrow_mut()
351 Ok(self.inner(py).borrow_mut()
342 .has_tracked_dir(HgPath::new(d.data(py)))
352 .has_tracked_dir(HgPath::new(d.data(py)))
343 .map_err(|e| {
353 .map_err(|e| {
344 PyErr::new::<exc::ValueError, _>(py, e.to_string())
354 PyErr::new::<exc::ValueError, _>(py, e.to_string())
345 })?
355 })?
346 .to_py_object(py))
356 .to_py_object(py))
347 }
357 }
348
358
349 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
359 def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
350 let d = d.extract::<PyBytes>(py)?;
360 let d = d.extract::<PyBytes>(py)?;
351 Ok(self.inner(py).borrow_mut()
361 Ok(self.inner(py).borrow_mut()
352 .has_dir(HgPath::new(d.data(py)))
362 .has_dir(HgPath::new(d.data(py)))
353 .map_err(|e| {
363 .map_err(|e| {
354 PyErr::new::<exc::ValueError, _>(py, e.to_string())
364 PyErr::new::<exc::ValueError, _>(py, e.to_string())
355 })?
365 })?
356 .to_py_object(py))
366 .to_py_object(py))
357 }
367 }
358
368
359 def write_v1(
369 def write_v1(
360 &self,
370 &self,
361 p1: PyObject,
371 p1: PyObject,
362 p2: PyObject,
372 p2: PyObject,
363 now: PyObject
373 now: PyObject
364 ) -> PyResult<PyBytes> {
374 ) -> PyResult<PyBytes> {
365 let now = Timestamp(now.extract(py)?);
375 let now = Timestamp(now.extract(py)?);
366
376
367 let mut inner = self.inner(py).borrow_mut();
377 let mut inner = self.inner(py).borrow_mut();
368 let parents = DirstateParents {
378 let parents = DirstateParents {
369 p1: extract_node_id(py, &p1)?,
379 p1: extract_node_id(py, &p1)?,
370 p2: extract_node_id(py, &p2)?,
380 p2: extract_node_id(py, &p2)?,
371 };
381 };
372 let result = inner.pack_v1(parents, now);
382 let result = inner.pack_v1(parents, now);
373 match result {
383 match result {
374 Ok(packed) => Ok(PyBytes::new(py, &packed)),
384 Ok(packed) => Ok(PyBytes::new(py, &packed)),
375 Err(_) => Err(PyErr::new::<exc::OSError, _>(
385 Err(_) => Err(PyErr::new::<exc::OSError, _>(
376 py,
386 py,
377 "Dirstate error".to_string(),
387 "Dirstate error".to_string(),
378 )),
388 )),
379 }
389 }
380 }
390 }
381
391
382 /// Returns new data together with whether that data should be appended to
392 /// Returns new data together with whether that data should be appended to
383 /// the existing data file whose content is at `self.on_disk` (True),
393 /// the existing data file whose content is at `self.on_disk` (True),
384 /// instead of written to a new data file (False).
394 /// instead of written to a new data file (False).
385 def write_v2(
395 def write_v2(
386 &self,
396 &self,
387 now: PyObject,
397 now: PyObject,
388 can_append: bool,
398 can_append: bool,
389 ) -> PyResult<PyObject> {
399 ) -> PyResult<PyObject> {
390 let now = Timestamp(now.extract(py)?);
400 let now = Timestamp(now.extract(py)?);
391
401
392 let mut inner = self.inner(py).borrow_mut();
402 let mut inner = self.inner(py).borrow_mut();
393 let result = inner.pack_v2(now, can_append);
403 let result = inner.pack_v2(now, can_append);
394 match result {
404 match result {
395 Ok((packed, tree_metadata, append)) => {
405 Ok((packed, tree_metadata, append)) => {
396 let packed = PyBytes::new(py, &packed);
406 let packed = PyBytes::new(py, &packed);
397 let tree_metadata = PyBytes::new(py, &tree_metadata);
407 let tree_metadata = PyBytes::new(py, &tree_metadata);
398 let tuple = (packed, tree_metadata, append);
408 let tuple = (packed, tree_metadata, append);
399 Ok(tuple.to_py_object(py).into_object())
409 Ok(tuple.to_py_object(py).into_object())
400 },
410 },
401 Err(_) => Err(PyErr::new::<exc::OSError, _>(
411 Err(_) => Err(PyErr::new::<exc::OSError, _>(
402 py,
412 py,
403 "Dirstate error".to_string(),
413 "Dirstate error".to_string(),
404 )),
414 )),
405 }
415 }
406 }
416 }
407
417
408 def filefoldmapasdict(&self) -> PyResult<PyDict> {
418 def filefoldmapasdict(&self) -> PyResult<PyDict> {
409 let dict = PyDict::new(py);
419 let dict = PyDict::new(py);
410 for item in self.inner(py).borrow_mut().iter() {
420 for item in self.inner(py).borrow_mut().iter() {
411 let (path, entry) = item.map_err(|e| v2_error(py, e))?;
421 let (path, entry) = item.map_err(|e| v2_error(py, e))?;
412 if entry.state != EntryState::Removed {
422 if entry.state != EntryState::Removed {
413 let key = normalize_case(path);
423 let key = normalize_case(path);
414 let value = path;
424 let value = path;
415 dict.set_item(
425 dict.set_item(
416 py,
426 py,
417 PyBytes::new(py, key.as_bytes()).into_object(),
427 PyBytes::new(py, key.as_bytes()).into_object(),
418 PyBytes::new(py, value.as_bytes()).into_object(),
428 PyBytes::new(py, value.as_bytes()).into_object(),
419 )?;
429 )?;
420 }
430 }
421 }
431 }
422 Ok(dict)
432 Ok(dict)
423 }
433 }
424
434
425 def __len__(&self) -> PyResult<usize> {
435 def __len__(&self) -> PyResult<usize> {
426 Ok(self.inner(py).borrow().len())
436 Ok(self.inner(py).borrow().len())
427 }
437 }
428
438
429 def __contains__(&self, key: PyObject) -> PyResult<bool> {
439 def __contains__(&self, key: PyObject) -> PyResult<bool> {
430 let key = key.extract::<PyBytes>(py)?;
440 let key = key.extract::<PyBytes>(py)?;
431 self.inner(py)
441 self.inner(py)
432 .borrow()
442 .borrow()
433 .contains_key(HgPath::new(key.data(py)))
443 .contains_key(HgPath::new(key.data(py)))
434 .map_err(|e| v2_error(py, e))
444 .map_err(|e| v2_error(py, e))
435 }
445 }
436
446
437 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
447 def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
438 let key = key.extract::<PyBytes>(py)?;
448 let key = key.extract::<PyBytes>(py)?;
439 let key = HgPath::new(key.data(py));
449 let key = HgPath::new(key.data(py));
440 match self
450 match self
441 .inner(py)
451 .inner(py)
442 .borrow()
452 .borrow()
443 .get(key)
453 .get(key)
444 .map_err(|e| v2_error(py, e))?
454 .map_err(|e| v2_error(py, e))?
445 {
455 {
446 Some(entry) => {
456 Some(entry) => {
447 Ok(make_dirstate_item(py, &entry)?)
457 Ok(make_dirstate_item(py, &entry)?)
448 },
458 },
449 None => Err(PyErr::new::<exc::KeyError, _>(
459 None => Err(PyErr::new::<exc::KeyError, _>(
450 py,
460 py,
451 String::from_utf8_lossy(key.as_bytes()),
461 String::from_utf8_lossy(key.as_bytes()),
452 )),
462 )),
453 }
463 }
454 }
464 }
455
465
456 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
466 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
457 let leaked_ref = self.inner(py).leak_immutable();
467 let leaked_ref = self.inner(py).leak_immutable();
458 DirstateMapKeysIterator::from_inner(
468 DirstateMapKeysIterator::from_inner(
459 py,
469 py,
460 unsafe { leaked_ref.map(py, |o| o.iter()) },
470 unsafe { leaked_ref.map(py, |o| o.iter()) },
461 )
471 )
462 }
472 }
463
473
464 def items(&self) -> PyResult<DirstateMapItemsIterator> {
474 def items(&self) -> PyResult<DirstateMapItemsIterator> {
465 let leaked_ref = self.inner(py).leak_immutable();
475 let leaked_ref = self.inner(py).leak_immutable();
466 DirstateMapItemsIterator::from_inner(
476 DirstateMapItemsIterator::from_inner(
467 py,
477 py,
468 unsafe { leaked_ref.map(py, |o| o.iter()) },
478 unsafe { leaked_ref.map(py, |o| o.iter()) },
469 )
479 )
470 }
480 }
471
481
472 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
482 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
473 let leaked_ref = self.inner(py).leak_immutable();
483 let leaked_ref = self.inner(py).leak_immutable();
474 DirstateMapKeysIterator::from_inner(
484 DirstateMapKeysIterator::from_inner(
475 py,
485 py,
476 unsafe { leaked_ref.map(py, |o| o.iter()) },
486 unsafe { leaked_ref.map(py, |o| o.iter()) },
477 )
487 )
478 }
488 }
479
489
480 // TODO all copymap* methods, see docstring above
490 // TODO all copymap* methods, see docstring above
481 def copymapcopy(&self) -> PyResult<PyDict> {
491 def copymapcopy(&self) -> PyResult<PyDict> {
482 let dict = PyDict::new(py);
492 let dict = PyDict::new(py);
483 for item in self.inner(py).borrow().copy_map_iter() {
493 for item in self.inner(py).borrow().copy_map_iter() {
484 let (key, value) = item.map_err(|e| v2_error(py, e))?;
494 let (key, value) = item.map_err(|e| v2_error(py, e))?;
485 dict.set_item(
495 dict.set_item(
486 py,
496 py,
487 PyBytes::new(py, key.as_bytes()),
497 PyBytes::new(py, key.as_bytes()),
488 PyBytes::new(py, value.as_bytes()),
498 PyBytes::new(py, value.as_bytes()),
489 )?;
499 )?;
490 }
500 }
491 Ok(dict)
501 Ok(dict)
492 }
502 }
493
503
494 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
504 def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
495 let key = key.extract::<PyBytes>(py)?;
505 let key = key.extract::<PyBytes>(py)?;
496 match self
506 match self
497 .inner(py)
507 .inner(py)
498 .borrow()
508 .borrow()
499 .copy_map_get(HgPath::new(key.data(py)))
509 .copy_map_get(HgPath::new(key.data(py)))
500 .map_err(|e| v2_error(py, e))?
510 .map_err(|e| v2_error(py, e))?
501 {
511 {
502 Some(copy) => Ok(PyBytes::new(py, copy.as_bytes())),
512 Some(copy) => Ok(PyBytes::new(py, copy.as_bytes())),
503 None => Err(PyErr::new::<exc::KeyError, _>(
513 None => Err(PyErr::new::<exc::KeyError, _>(
504 py,
514 py,
505 String::from_utf8_lossy(key.data(py)),
515 String::from_utf8_lossy(key.data(py)),
506 )),
516 )),
507 }
517 }
508 }
518 }
509 def copymap(&self) -> PyResult<CopyMap> {
519 def copymap(&self) -> PyResult<CopyMap> {
510 CopyMap::from_inner(py, self.clone_ref(py))
520 CopyMap::from_inner(py, self.clone_ref(py))
511 }
521 }
512
522
513 def copymaplen(&self) -> PyResult<usize> {
523 def copymaplen(&self) -> PyResult<usize> {
514 Ok(self.inner(py).borrow().copy_map_len())
524 Ok(self.inner(py).borrow().copy_map_len())
515 }
525 }
516 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
526 def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
517 let key = key.extract::<PyBytes>(py)?;
527 let key = key.extract::<PyBytes>(py)?;
518 self.inner(py)
528 self.inner(py)
519 .borrow()
529 .borrow()
520 .copy_map_contains_key(HgPath::new(key.data(py)))
530 .copy_map_contains_key(HgPath::new(key.data(py)))
521 .map_err(|e| v2_error(py, e))
531 .map_err(|e| v2_error(py, e))
522 }
532 }
523 def copymapget(
533 def copymapget(
524 &self,
534 &self,
525 key: PyObject,
535 key: PyObject,
526 default: Option<PyObject>
536 default: Option<PyObject>
527 ) -> PyResult<Option<PyObject>> {
537 ) -> PyResult<Option<PyObject>> {
528 let key = key.extract::<PyBytes>(py)?;
538 let key = key.extract::<PyBytes>(py)?;
529 match self
539 match self
530 .inner(py)
540 .inner(py)
531 .borrow()
541 .borrow()
532 .copy_map_get(HgPath::new(key.data(py)))
542 .copy_map_get(HgPath::new(key.data(py)))
533 .map_err(|e| v2_error(py, e))?
543 .map_err(|e| v2_error(py, e))?
534 {
544 {
535 Some(copy) => Ok(Some(
545 Some(copy) => Ok(Some(
536 PyBytes::new(py, copy.as_bytes()).into_object(),
546 PyBytes::new(py, copy.as_bytes()).into_object(),
537 )),
547 )),
538 None => Ok(default),
548 None => Ok(default),
539 }
549 }
540 }
550 }
541 def copymapsetitem(
551 def copymapsetitem(
542 &self,
552 &self,
543 key: PyObject,
553 key: PyObject,
544 value: PyObject
554 value: PyObject
545 ) -> PyResult<PyObject> {
555 ) -> PyResult<PyObject> {
546 let key = key.extract::<PyBytes>(py)?;
556 let key = key.extract::<PyBytes>(py)?;
547 let value = value.extract::<PyBytes>(py)?;
557 let value = value.extract::<PyBytes>(py)?;
548 self.inner(py)
558 self.inner(py)
549 .borrow_mut()
559 .borrow_mut()
550 .copy_map_insert(
560 .copy_map_insert(
551 HgPathBuf::from_bytes(key.data(py)),
561 HgPathBuf::from_bytes(key.data(py)),
552 HgPathBuf::from_bytes(value.data(py)),
562 HgPathBuf::from_bytes(value.data(py)),
553 )
563 )
554 .map_err(|e| v2_error(py, e))?;
564 .map_err(|e| v2_error(py, e))?;
555 Ok(py.None())
565 Ok(py.None())
556 }
566 }
557 def copymappop(
567 def copymappop(
558 &self,
568 &self,
559 key: PyObject,
569 key: PyObject,
560 default: Option<PyObject>
570 default: Option<PyObject>
561 ) -> PyResult<Option<PyObject>> {
571 ) -> PyResult<Option<PyObject>> {
562 let key = key.extract::<PyBytes>(py)?;
572 let key = key.extract::<PyBytes>(py)?;
563 match self
573 match self
564 .inner(py)
574 .inner(py)
565 .borrow_mut()
575 .borrow_mut()
566 .copy_map_remove(HgPath::new(key.data(py)))
576 .copy_map_remove(HgPath::new(key.data(py)))
567 .map_err(|e| v2_error(py, e))?
577 .map_err(|e| v2_error(py, e))?
568 {
578 {
569 Some(_) => Ok(None),
579 Some(_) => Ok(None),
570 None => Ok(default),
580 None => Ok(default),
571 }
581 }
572 }
582 }
573
583
574 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
584 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
575 let leaked_ref = self.inner(py).leak_immutable();
585 let leaked_ref = self.inner(py).leak_immutable();
576 CopyMapKeysIterator::from_inner(
586 CopyMapKeysIterator::from_inner(
577 py,
587 py,
578 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
588 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
579 )
589 )
580 }
590 }
581
591
582 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
592 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
583 let leaked_ref = self.inner(py).leak_immutable();
593 let leaked_ref = self.inner(py).leak_immutable();
584 CopyMapItemsIterator::from_inner(
594 CopyMapItemsIterator::from_inner(
585 py,
595 py,
586 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
596 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
587 )
597 )
588 }
598 }
589
599
590 def tracked_dirs(&self) -> PyResult<PyList> {
600 def tracked_dirs(&self) -> PyResult<PyList> {
591 let dirs = PyList::new(py, &[]);
601 let dirs = PyList::new(py, &[]);
592 for path in self.inner(py).borrow_mut().iter_tracked_dirs()
602 for path in self.inner(py).borrow_mut().iter_tracked_dirs()
593 .map_err(|e |dirstate_error(py, e))?
603 .map_err(|e |dirstate_error(py, e))?
594 {
604 {
595 let path = path.map_err(|e| v2_error(py, e))?;
605 let path = path.map_err(|e| v2_error(py, e))?;
596 let path = PyBytes::new(py, path.as_bytes());
606 let path = PyBytes::new(py, path.as_bytes());
597 dirs.append(py, path.into_object())
607 dirs.append(py, path.into_object())
598 }
608 }
599 Ok(dirs)
609 Ok(dirs)
600 }
610 }
601
611
602 def debug_iter(&self) -> PyResult<PyList> {
612 def debug_iter(&self) -> PyResult<PyList> {
603 let dirs = PyList::new(py, &[]);
613 let dirs = PyList::new(py, &[]);
604 for item in self.inner(py).borrow().debug_iter() {
614 for item in self.inner(py).borrow().debug_iter() {
605 let (path, (state, mode, size, mtime)) =
615 let (path, (state, mode, size, mtime)) =
606 item.map_err(|e| v2_error(py, e))?;
616 item.map_err(|e| v2_error(py, e))?;
607 let path = PyBytes::new(py, path.as_bytes());
617 let path = PyBytes::new(py, path.as_bytes());
608 let item = make_dirstate_item_raw(py, state, mode, size, mtime)?;
618 let item = make_dirstate_item_raw(py, state, mode, size, mtime)?;
609 dirs.append(py, (path, item).to_py_object(py).into_object())
619 dirs.append(py, (path, item).to_py_object(py).into_object())
610 }
620 }
611 Ok(dirs)
621 Ok(dirs)
612 }
622 }
613 });
623 });
614
624
615 impl DirstateMap {
625 impl DirstateMap {
616 pub fn get_inner_mut<'a>(
626 pub fn get_inner_mut<'a>(
617 &'a self,
627 &'a self,
618 py: Python<'a>,
628 py: Python<'a>,
619 ) -> RefMut<'a, Box<dyn DirstateMapMethods + Send>> {
629 ) -> RefMut<'a, Box<dyn DirstateMapMethods + Send>> {
620 self.inner(py).borrow_mut()
630 self.inner(py).borrow_mut()
621 }
631 }
622 fn translate_key(
632 fn translate_key(
623 py: Python,
633 py: Python,
624 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
634 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
625 ) -> PyResult<Option<PyBytes>> {
635 ) -> PyResult<Option<PyBytes>> {
626 let (f, _entry) = res.map_err(|e| v2_error(py, e))?;
636 let (f, _entry) = res.map_err(|e| v2_error(py, e))?;
627 Ok(Some(PyBytes::new(py, f.as_bytes())))
637 Ok(Some(PyBytes::new(py, f.as_bytes())))
628 }
638 }
629 fn translate_key_value(
639 fn translate_key_value(
630 py: Python,
640 py: Python,
631 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
641 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
632 ) -> PyResult<Option<(PyBytes, PyObject)>> {
642 ) -> PyResult<Option<(PyBytes, PyObject)>> {
633 let (f, entry) = res.map_err(|e| v2_error(py, e))?;
643 let (f, entry) = res.map_err(|e| v2_error(py, e))?;
634 Ok(Some((
644 Ok(Some((
635 PyBytes::new(py, f.as_bytes()),
645 PyBytes::new(py, f.as_bytes()),
636 make_dirstate_item(py, &entry)?,
646 make_dirstate_item(py, &entry)?,
637 )))
647 )))
638 }
648 }
639 }
649 }
640
650
641 py_shared_iterator!(
651 py_shared_iterator!(
642 DirstateMapKeysIterator,
652 DirstateMapKeysIterator,
643 UnsafePyLeaked<StateMapIter<'static>>,
653 UnsafePyLeaked<StateMapIter<'static>>,
644 DirstateMap::translate_key,
654 DirstateMap::translate_key,
645 Option<PyBytes>
655 Option<PyBytes>
646 );
656 );
647
657
648 py_shared_iterator!(
658 py_shared_iterator!(
649 DirstateMapItemsIterator,
659 DirstateMapItemsIterator,
650 UnsafePyLeaked<StateMapIter<'static>>,
660 UnsafePyLeaked<StateMapIter<'static>>,
651 DirstateMap::translate_key_value,
661 DirstateMap::translate_key_value,
652 Option<(PyBytes, PyObject)>
662 Option<(PyBytes, PyObject)>
653 );
663 );
654
664
655 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<Node> {
665 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<Node> {
656 let bytes = obj.extract::<PyBytes>(py)?;
666 let bytes = obj.extract::<PyBytes>(py)?;
657 match bytes.data(py).try_into() {
667 match bytes.data(py).try_into() {
658 Ok(s) => Ok(s),
668 Ok(s) => Ok(s),
659 Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
669 Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
660 }
670 }
661 }
671 }
662
672
663 pub(super) fn v2_error(py: Python<'_>, _: DirstateV2ParseError) -> PyErr {
673 pub(super) fn v2_error(py: Python<'_>, _: DirstateV2ParseError) -> PyErr {
664 PyErr::new::<exc::ValueError, _>(py, "corrupted dirstate-v2")
674 PyErr::new::<exc::ValueError, _>(py, "corrupted dirstate-v2")
665 }
675 }
666
676
667 fn dirstate_error(py: Python<'_>, e: DirstateError) -> PyErr {
677 fn dirstate_error(py: Python<'_>, e: DirstateError) -> PyErr {
668 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
678 PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
669 }
679 }
@@ -1,53 +1,56 b''
1 use cpython::{PyBytes, Python};
1 use cpython::{PyBytes, Python};
2 use stable_deref_trait::StableDeref;
2
3
3 /// Safe abstraction over a `PyBytes` together with the `&[u8]` slice
4 /// Safe abstraction over a `PyBytes` together with the `&[u8]` slice
4 /// that borrows it. Implements `Deref<Target = [u8]>`.
5 /// that borrows it. Implements `Deref<Target = [u8]>`.
5 ///
6 ///
6 /// Calling `PyBytes::data` requires a GIL marker but we want to access the
7 /// Calling `PyBytes::data` requires a GIL marker but we want to access the
7 /// data in a thread that (ideally) does not need to acquire the GIL.
8 /// data in a thread that (ideally) does not need to acquire the GIL.
8 /// This type allows separating the call an the use.
9 /// This type allows separating the call an the use.
9 ///
10 ///
10 /// It also enables using a (wrapped) `PyBytes` in GIL-unaware generic code.
11 /// It also enables using a (wrapped) `PyBytes` in GIL-unaware generic code.
11 pub struct PyBytesDeref {
12 pub struct PyBytesDeref {
12 #[allow(unused)]
13 #[allow(unused)]
13 keep_alive: PyBytes,
14 keep_alive: PyBytes,
14
15
15 /// Borrows the buffer inside `self.keep_alive`,
16 /// Borrows the buffer inside `self.keep_alive`,
16 /// but the borrow-checker cannot express self-referential structs.
17 /// but the borrow-checker cannot express self-referential structs.
17 data: *const [u8],
18 data: *const [u8],
18 }
19 }
19
20
20 impl PyBytesDeref {
21 impl PyBytesDeref {
21 pub fn new(py: Python, bytes: PyBytes) -> Self {
22 pub fn new(py: Python, bytes: PyBytes) -> Self {
22 Self {
23 Self {
23 data: bytes.data(py),
24 data: bytes.data(py),
24 keep_alive: bytes,
25 keep_alive: bytes,
25 }
26 }
26 }
27 }
27
28
28 pub fn unwrap(self) -> PyBytes {
29 pub fn unwrap(self) -> PyBytes {
29 self.keep_alive
30 self.keep_alive
30 }
31 }
31 }
32 }
32
33
33 impl std::ops::Deref for PyBytesDeref {
34 impl std::ops::Deref for PyBytesDeref {
34 type Target = [u8];
35 type Target = [u8];
35
36
36 fn deref(&self) -> &[u8] {
37 fn deref(&self) -> &[u8] {
37 // Safety: the raw pointer is valid as long as the PyBytes is still
38 // Safety: the raw pointer is valid as long as the PyBytes is still
38 // alive, and the returned slice borrows `self`.
39 // alive, and the returned slice borrows `self`.
39 unsafe { &*self.data }
40 unsafe { &*self.data }
40 }
41 }
41 }
42 }
42
43
44 unsafe impl StableDeref for PyBytesDeref {}
45
43 fn require_send<T: Send>() {}
46 fn require_send<T: Send>() {}
44
47
45 #[allow(unused)]
48 #[allow(unused)]
46 fn static_assert_pybytes_is_send() {
49 fn static_assert_pybytes_is_send() {
47 require_send::<PyBytes>;
50 require_send::<PyBytes>;
48 }
51 }
49
52
50 // Safety: PyBytes is Send. Raw pointers are not by default,
53 // Safety: PyBytes is Send. Raw pointers are not by default,
51 // but here sending one to another thread is fine since we ensure it stays
54 // but here sending one to another thread is fine since we ensure it stays
52 // valid.
55 // valid.
53 unsafe impl Send for PyBytesDeref {}
56 unsafe impl Send for PyBytesDeref {}
General Comments 0
You need to be logged in to leave comments. Login now