annotate rust/hg-core/src/dirstate/parsers.rs @ 53042:cdd7bf612c7b stable tip

bundle-spec: properly format boolean parameter (issue6960) This was breaking automatic clone bundle generation. This changeset fixes it and add a test to catch it in the future.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 11 Mar 2025 02:29:42 +0100
parents b422acba55f1
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
52299
b422acba55f1 rust-dirstate: remove star exports
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52048
diff changeset
6 use crate::dirstate::entry::{DirstateEntry, EntryState};
46439
68a15b5a7e58 rust: Replace DirstatePackError with HgError
Simon Sapin <simon.sapin@octobus.net>
parents: 45646
diff changeset
7 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
8 use crate::utils::hg_path::HgPath;
52299
b422acba55f1 rust-dirstate: remove star exports
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52048
diff changeset
9 use crate::DirstateParents;
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
10 use byteorder::{BigEndian, WriteBytesExt};
48018
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
11 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
12
d1786c1d34fa rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
13 /// 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
14 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
15 /// 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
16 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
17
45357
27424779c5b8 hg-core: make parse_dirstate return references rather than update hashmaps
Antoine Cezar <antoine.cezar@octobus.net>
parents: 44973
diff changeset
18 type ParseResult<'a> = (
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
19 &'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
20 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
21 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
22 );
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
23
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
24 pub fn parse_dirstate_parents(
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
25 contents: &[u8],
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
26 ) -> 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
27 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
28 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
29 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
30 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
31 "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
32 ))
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
33 })?;
46601
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
34 Ok(parents)
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
35 }
755c31a1caf9 rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents: 46595
diff changeset
36
49913
c15b415d1bff rust: use `logging_timer` instead of `micro_timer`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49631
diff changeset
37 #[logging_timer::time("trace")]
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
38 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
39 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
40 let mut entries = Vec::new();
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
41 let parents =
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
42 parse_dirstate_entries(contents, |path, entry, copy_source| {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
43 if let Some(source) = copy_source {
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
44 copies.push((path, source));
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
45 }
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
46 entries.push((path, *entry));
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
47 Ok(())
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
48 })?;
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
49 Ok((parents, entries, copies))
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
50 }
42302
d1786c1d34fa rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
51
48018
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
52 #[derive(BytesCast)]
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
53 #[repr(C)]
48022
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
54 struct RawEntry {
48018
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
55 state: u8,
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
56 mode: unaligned::I32Be,
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
57 size: unaligned::I32Be,
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
58 mtime: unaligned::I32Be,
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
59 length: unaligned::I32Be,
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
60 }
08efe5945d2b rust: Move DirstateEntry to its own module
Simon Sapin <simon.sapin@octobus.net>
parents: 47351
diff changeset
61
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
62 pub fn parse_dirstate_entries<'a>(
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
63 mut contents: &'a [u8],
47335
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
64 mut each_entry: impl FnMut(
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
65 &'a HgPath,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
66 &DirstateEntry,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
67 Option<&'a HgPath>,
ed1583a845d2 dirstate-v2: Make more APIs fallible, returning Result
Simon Sapin <simon.sapin@octobus.net>
parents: 47330
diff changeset
68 ) -> Result<(), HgError>,
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
69 ) -> Result<&'a DirstateParents, HgError> {
50533
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
70 let mut entry_idx = 0;
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
71 let original_len = contents.len();
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
72 let (parents, rest) =
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
73 DirstateParents::from_bytes(contents).map_err(|_| {
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
74 HgError::corrupted(format!(
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
75 "Too little data for dirstate: {} bytes.",
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
76 original_len
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
77 ))
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
78 })?;
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
79 contents = rest;
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
80 while !contents.is_empty() {
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
81 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
82 .map_err(|_| HgError::corrupted(format!(
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
83 "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
84 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
85
48022
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
86 let entry = DirstateEntry::from_v1_data(
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
87 EntryState::try_from(raw_entry.state)?,
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
88 raw_entry.mode.get(),
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
89 raw_entry.size.get(),
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
90 raw_entry.mtime.get(),
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
91 );
50533
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
92 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
93 let (paths, rest) =
50533
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
94 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
95 .map_err(|_|
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
96 HgError::corrupted(format!(
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
97 "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
98 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
99 )?;
42302
d1786c1d34fa rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
100
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
101 // `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
102 // byte
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
103 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
104 let path = HgPath::new(
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
105 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
106 );
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
107 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
108 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
109
50533
475c170bb815 dirstate: better error messages when dirstate is corrupted
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 49913
diff changeset
110 entry_idx += 1;
46594
f88e8ae0aa8f rust: Rewrite dirstate parsing usin the `bytes-cast` crate
Simon Sapin <simon.sapin@octobus.net>
parents: 46440
diff changeset
111 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
112 }
47097
e66ea29e2b1a dirstate-tree: Implement DirstateMap::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46890
diff changeset
113 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
114 }
d1786c1d34fa rust-dirstate: add rust implementation of `parse_dirstate` and `pack_dirstate`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
115
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
116 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
117 filename: &HgPath,
cd8ca38fccff rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
118 copy_source: Option<&HgPath>,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
119 ) -> usize {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
120 filename.len()
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
121 + if let Some(source) = copy_source {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
122 b"\0".len() + source.len()
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
123 } else {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
124 0
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
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
128 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
129 filename: &HgPath,
cd8ca38fccff rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
130 copy_source: Option<&HgPath>,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
131 ) -> usize {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
132 MIN_ENTRY_SIZE
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
133 + 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
134 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
135
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
136 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
137 filename: &HgPath,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
138 entry: &DirstateEntry,
47124
cd8ca38fccff rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs
Simon Sapin <simon.sapin@octobus.net>
parents: 47102
diff changeset
139 copy_source: Option<&HgPath>,
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
140 packed: &mut Vec<u8>,
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
141 ) {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
142 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
143 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
144
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
145 // 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
146 packed.write_u8(state).unwrap();
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
147 packed.write_i32::<BigEndian>(mode).unwrap();
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
148 packed.write_i32::<BigEndian>(size).unwrap();
f2a9db29cb2d rust: Make the fields of DirstateEntry private
Simon Sapin <simon.sapin@octobus.net>
parents: 48018
diff changeset
149 packed.write_i32::<BigEndian>(mtime).unwrap();
47102
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
150 packed.write_i32::<BigEndian>(length as i32).unwrap();
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
151 packed.extend(filename.as_bytes());
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
152 if let Some(source) = copy_source {
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
153 packed.push(b'\0');
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
154 packed.extend(source.as_bytes());
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
155 }
d6c94ca40863 dirstate-tree: Serialize to disk
Simon Sapin <simon.sapin@octobus.net>
parents: 47101
diff changeset
156 }