##// END OF EJS Templates
rust-status: error on non-existent files in file_set...
rust-status: error on non-existent files in file_set file_set here consists of the files that were explicitly specified on the command line. Erroring on them matches the behavior of Python status.

File last commit:

r51429:475c170b default
r51756:26407210 default
Show More
parsers.rs
150 lines | 4.7 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 // Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.
Simon Sapin
rust: Replace DirstatePackError with HgError...
r47168 use crate::errors::HgError;
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 use crate::utils::hg_path::HgPath;
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 use crate::{dirstate::EntryState, DirstateEntry, DirstateParents};
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 use byteorder::{BigEndian, WriteBytesExt};
Simon Sapin
rust: Move DirstateEntry to its own module...
r48830 use bytes_cast::{unaligned, BytesCast};
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
/// Parents are stored in the dirstate as byte hashes.
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993 pub const PARENT_SIZE: usize = 20;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 /// Dirstate entries have a static part of 8 + 32 + 32 + 32 + 32 bits.
const MIN_ENTRY_SIZE: usize = 17;
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 type ParseResult<'a> = (
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 &'a DirstateParents,
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 Vec<(&'a HgPath, DirstateEntry)>,
Vec<(&'a HgPath, &'a HgPath)>,
);
Raphaël Gomès
rust-parsers: switch to parse/pack_dirstate to mutate-on-loop...
r42993
Simon Sapin
rhg: Add support for the blackbox extension...
r47343 pub fn parse_dirstate_parents(
contents: &[u8],
) -> Result<&DirstateParents, HgError> {
let (parents, _rest) = DirstateParents::from_bytes(contents)
.map_err(|_| HgError::corrupted("Too little data for dirstate."))?;
Ok(parents)
}
Raphaël Gomès
rust: use `logging_timer` instead of `micro_timer`...
r50808 #[logging_timer::time("trace")]
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 pub fn parse_dirstate(contents: &[u8]) -> Result<ParseResult, HgError> {
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 let mut copies = Vec::new();
let mut entries = Vec::new();
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 let parents =
parse_dirstate_entries(contents, |path, entry, copy_source| {
if let Some(source) = copy_source {
copies.push((path, source));
}
entries.push((path, *entry));
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 Ok(())
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 })?;
Ok((parents, entries, copies))
}
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Move DirstateEntry to its own module...
r48830 #[derive(BytesCast)]
#[repr(C)]
Simon Sapin
rust: Make the fields of DirstateEntry private...
r48834 struct RawEntry {
Simon Sapin
rust: Move DirstateEntry to its own module...
r48830 state: u8,
mode: unaligned::I32Be,
size: unaligned::I32Be,
mtime: unaligned::I32Be,
length: unaligned::I32Be,
}
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 pub fn parse_dirstate_entries<'a>(
mut contents: &'a [u8],
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 mut each_entry: impl FnMut(
&'a HgPath,
&DirstateEntry,
Option<&'a HgPath>,
) -> Result<(), HgError>,
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 ) -> Result<&'a DirstateParents, HgError> {
Arseniy Alekseyev
dirstate: better error messages when dirstate is corrupted...
r51429 let mut entry_idx = 0;
let original_len = contents.len();
let (parents, rest) =
DirstateParents::from_bytes(contents).map_err(|_| {
HgError::corrupted(format!(
"Too little data for dirstate: {} bytes.",
original_len
))
})?;
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 contents = rest;
while !contents.is_empty() {
let (raw_entry, rest) = RawEntry::from_bytes(contents)
Arseniy Alekseyev
dirstate: better error messages when dirstate is corrupted...
r51429 .map_err(|_| HgError::corrupted(format!(
"dirstate corrupted: ran out of bytes at entry header {}, offset {}.",
entry_idx, original_len-contents.len())))?;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Make the fields of DirstateEntry private...
r48834 let entry = DirstateEntry::from_v1_data(
EntryState::try_from(raw_entry.state)?,
raw_entry.mode.get(),
raw_entry.size.get(),
raw_entry.mtime.get(),
);
Arseniy Alekseyev
dirstate: better error messages when dirstate is corrupted...
r51429 let filename_len = raw_entry.length.get() as usize;
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 let (paths, rest) =
Arseniy Alekseyev
dirstate: better error messages when dirstate is corrupted...
r51429 u8::slice_from_bytes(rest, filename_len)
.map_err(|_|
HgError::corrupted(format!(
"dirstate corrupted: ran out of bytes at entry {}, offset {} (expected {} bytes).",
entry_idx, original_len-contents.len(), filename_len))
)?;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 // `paths` is either a single path, or two paths separated by a NULL
// byte
let mut iter = paths.splitn(2, |&byte| byte == b'\0');
let path = HgPath::new(
iter.next().expect("splitn always yields at least one item"),
);
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 let copy_source = iter.next().map(HgPath::new);
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 each_entry(path, &entry, copy_source)?;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617
Arseniy Alekseyev
dirstate: better error messages when dirstate is corrupted...
r51429 entry_idx += 1;
Simon Sapin
rust: Rewrite dirstate parsing usin the `bytes-cast` crate...
r47336 contents = rest;
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
dirstate-tree: Implement DirstateMap::read...
r47867 Ok(parents)
Raphaël Gomès
rust-dirstate: create dirstate submodule...
r42617 }
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 fn packed_filename_and_copy_source_size(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 ) -> usize {
filename.len()
+ if let Some(source) = copy_source {
b"\0".len() + source.len()
} else {
0
}
}
pub fn packed_entry_size(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 ) -> usize {
MIN_ENTRY_SIZE
+ packed_filename_and_copy_source_size(filename, copy_source)
}
pub fn pack_entry(
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 filename: &HgPath,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 entry: &DirstateEntry,
Simon Sapin
rust: Use `&HgPath` instead of `&HgPathBuf` in may APIs...
r47894 copy_source: Option<&HgPath>,
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 packed: &mut Vec<u8>,
) {
let length = packed_filename_and_copy_source_size(filename, copy_source);
Simon Sapin
rust: Make the fields of DirstateEntry private...
r48834 let (state, mode, size, mtime) = entry.v1_data();
Simon Sapin
dirstate-tree: Serialize to disk...
r47872
// Unwrapping because `impl std::io::Write for Vec<u8>` never errors
Simon Sapin
rust: Make the fields of DirstateEntry private...
r48834 packed.write_u8(state).unwrap();
packed.write_i32::<BigEndian>(mode).unwrap();
packed.write_i32::<BigEndian>(size).unwrap();
packed.write_i32::<BigEndian>(mtime).unwrap();
Simon Sapin
dirstate-tree: Serialize to disk...
r47872 packed.write_i32::<BigEndian>(length as i32).unwrap();
packed.extend(filename.as_bytes());
if let Some(source) = copy_source {
packed.push(b'\0');
packed.extend(source.as_bytes());
}
}