Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/dirstate/parsers.rs @ 52048:db5c202eff36
rust-parsers: use the same error message as with the higher-level code
This can happen at two places, but it's not really enough time to justify it
being refactored. Let's ensure we have the same error message, the newer one
being slightly more helpful.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 03 Oct 2024 00:31:25 +0200 |
parents | 475c170bb815 |
children | b422acba55f1 |
rev | line source |
---|---|
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
1 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net> |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 // |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
3 // This software may be used and distributed according to the terms of the |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
4 // GNU General Public License version 2 or any later version. |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
5 |
46439
68a15b5a7e58
rust: Replace DirstatePackError with HgError
Simon Sapin <simon.sapin@octobus.net>
parents:
45646
diff
changeset
|
6 use crate::errors::HgError; |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
7 use crate::utils::hg_path::HgPath; |
48068
bf8837e3d7ce
dirstate: Remove the flat Rust DirstateMap implementation
Simon Sapin <simon.sapin@octobus.net>
parents:
48022
diff
changeset
|
8 use crate::{dirstate::EntryState, DirstateEntry, DirstateParents}; |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
9 use byteorder::{BigEndian, WriteBytesExt}; |
48018
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
10 use bytes_cast::{unaligned, BytesCast}; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
11 |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
12 /// Parents are stored in the dirstate as byte hashes. |
42748
7cae6bc29ff9
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
13 pub const PARENT_SIZE: usize = 20; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 /// Dirstate entries have a static part of 8 + 32 + 32 + 32 + 32 bits. |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 const MIN_ENTRY_SIZE: usize = 17; |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 |
45357
27424779c5b8
hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44973
diff
changeset
|
17 type ParseResult<'a> = ( |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
18 &'a DirstateParents, |
45357
27424779c5b8
hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44973
diff
changeset
|
19 Vec<(&'a HgPath, DirstateEntry)>, |
27424779c5b8
hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44973
diff
changeset
|
20 Vec<(&'a HgPath, &'a HgPath)>, |
27424779c5b8
hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents:
44973
diff
changeset
|
21 ); |
42748
7cae6bc29ff9
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Rapha?l Gom?s <rgomes@octobus.net>
parents:
42609
diff
changeset
|
22 |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
23 pub fn parse_dirstate_parents( |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
24 contents: &[u8], |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
25 ) -> Result<&DirstateParents, HgError> { |
52048
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
26 let contents_len = contents.len(); |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
27 let (parents, _rest) = |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
28 DirstateParents::from_bytes(contents).map_err(|_| { |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
29 HgError::corrupted(format!( |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
30 "Too little data for dirstate: {contents_len} bytes.", |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
31 )) |
db5c202eff36
rust-parsers: use the same error message as with the higher-level code
Rapha?l Gom?s <rgomes@octobus.net>
parents:
50533
diff
changeset
|
32 })?; |
46601
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
33 Ok(parents) |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
34 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46595
diff
changeset
|
35 |
49913
c15b415d1bff
rust: use `logging_timer` instead of `micro_timer`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49631
diff
changeset
|
36 #[logging_timer::time("trace")] |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
37 pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> { |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
38 let mut copies = Vec::new(); |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
39 let mut entries = Vec::new(); |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
40 let parents = |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
41 parse_dirstate_entries(contents, |path, entry, copy_source| { |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
42 if let Some(source) = copy_source { |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
43 copies.push((path, source)); |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
44 } |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
45 entries.push((path, *entry)); |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
46 Ok(()) |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
47 })?; |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
48 Ok((parents, entries, copies)) |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
49 } |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
50 |
48018
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
51 #[derive(BytesCast)] |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
52 #[repr(C)] |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
53 struct RawEntry { |
48018
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
54 state: u8, |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
55 mode: unaligned::I32Be, |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
56 size: unaligned::I32Be, |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
57 mtime: unaligned::I32Be, |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
58 length: unaligned::I32Be, |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
59 } |
08efe5945d2b
rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents:
47351
diff
changeset
|
60 |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
61 pub fn parse_dirstate_entries<'a>( |
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
62 mut contents: &'a [u8], |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
63 mut each_entry: impl FnMut( |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
64 &'a HgPath, |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
65 &DirstateEntry, |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
66 Option<&'a HgPath>, |
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
67 ) -> Result<(), HgError>, |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
68 ) -> Result<&'a DirstateParents, HgError> { |
50533
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
69 let mut entry_idx = 0; |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
70 let original_len = contents.len(); |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
71 let (parents, rest) = |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
72 DirstateParents::from_bytes(contents).map_err(|_| { |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
73 HgError::corrupted(format!( |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
74 "Too little data for dirstate: {} bytes.", |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
75 original_len |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
76 )) |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
77 })?; |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
78 contents = rest; |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
79 while !contents.is_empty() { |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
80 let (raw_entry, rest) = RawEntry::from_bytes(contents) |
50533
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
81 .map_err(|_| HgError::corrupted(format!( |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
82 "dirstate corrupted: ran out of bytes at entry header {}, offset {}.", |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
83 entry_idx, original_len-contents.len())))?; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
84 |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
85 let entry = DirstateEntry::from_v1_data( |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
86 EntryState::try_from(raw_entry.state)?, |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
87 raw_entry.mode.get(), |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
88 raw_entry.size.get(), |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
89 raw_entry.mtime.get(), |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
90 ); |
50533
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
91 let filename_len = raw_entry.length.get() as usize; |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
92 let (paths, rest) = |
50533
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
93 u8::slice_from_bytes(rest, filename_len) |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
94 .map_err(|_| |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
95 HgError::corrupted(format!( |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
96 "dirstate corrupted: ran out of bytes at entry {}, offset {} (expected {} bytes).", |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
97 entry_idx, original_len-contents.len(), filename_len)) |
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
98 )?; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
99 |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
100 // `paths` is either a single path, or two paths separated by a NULL |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
101 // byte |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
102 let mut iter = paths.splitn(2, |&byte| byte == b'\0'); |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
103 let path = HgPath::new( |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
104 iter.next().expect("splitn always yields at least one item"), |
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
105 ); |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
106 let copy_source = iter.next().map(HgPath::new); |
47335
ed1583a845d2
dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents:
47330
diff
changeset
|
107 each_entry(path, &entry, copy_source)?; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
108 |
50533
475c170bb815
dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49913
diff
changeset
|
109 entry_idx += 1; |
46594
f88e8ae0aa8f
rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents:
46440
diff
changeset
|
110 contents = rest; |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
111 } |
47097
e66ea29e2b1a
dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46890
diff
changeset
|
112 Ok(parents) |
42302
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
113 } |
d1786c1d34fa
rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
114 |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
115 fn packed_filename_and_copy_source_size( |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
116 filename: &HgPath, |
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
117 copy_source: Option<&HgPath>, |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
118 ) -> usize { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
119 filename.len() |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
120 + if let Some(source) = copy_source { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
121 b"\0".len() + source.len() |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
122 } else { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
123 0 |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
124 } |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
125 } |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
126 |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
127 pub fn packed_entry_size( |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
128 filename: &HgPath, |
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
129 copy_source: Option<&HgPath>, |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
130 ) -> usize { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
131 MIN_ENTRY_SIZE |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
132 + packed_filename_and_copy_source_size(filename, copy_source) |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
133 } |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
134 |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
135 pub fn pack_entry( |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
136 filename: &HgPath, |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
137 entry: &DirstateEntry, |
47124
cd8ca38fccff
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents:
47102
diff
changeset
|
138 copy_source: Option<&HgPath>, |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
139 packed: &mut Vec<u8>, |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
140 ) { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
141 let length = packed_filename_and_copy_source_size(filename, copy_source); |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
142 let (state, mode, size, mtime) = entry.v1_data(); |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
143 |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
144 // Unwrapping because `impl std::io::Write for Vec<u8>` never errors |
48022
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
145 packed.write_u8(state).unwrap(); |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
146 packed.write_i32::<BigEndian>(mode).unwrap(); |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
147 packed.write_i32::<BigEndian>(size).unwrap(); |
f2a9db29cb2d
rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents:
48018
diff
changeset
|
148 packed.write_i32::<BigEndian>(mtime).unwrap(); |
47102
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
149 packed.write_i32::<BigEndian>(length as i32).unwrap(); |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
150 packed.extend(filename.as_bytes()); |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
151 if let Some(source) = copy_source { |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
152 packed.push(b'\0'); |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
153 packed.extend(source.as_bytes()); |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
154 } |
d6c94ca40863
dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents:
47101
diff
changeset
|
155 } |