##// END OF EJS Templates
rust: Make OwningDirstateMap generic and move it into hg-core...
rust: Make OwningDirstateMap generic and move it into hg-core This will enable using it in rhg too. The `OwningDirstateMap::new_empty` constructor is generic and accepts a value of any type that gives acces to a bytes buffer. That buffer must stay valid as long as the value hasn’t been dropped, and must keep its memory address even if the value is moved. The `StableDeref` marker trait encodes those constraints. Previously no trait was needed because the value was always of type `PyBytes` which we know satisfies those constraints. The buffer type is ereased in the struct itself through boxing and dynamic dispatch, in order to simplify other signatures that mention `OwningDirstateMap`. Differential Revision: https://phab.mercurial-scm.org/D11396

File last commit:

r48756:e02f9af7 default
r48766:4afd6cc4 default
Show More
dirstate_map.rs
494 lines | 14.8 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 // dirstate_map.rs
//
// 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: Add a Timestamp struct instead of abusing Duration...
r47871 use crate::dirstate::parsers::Timestamp;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 use crate::{
Simon Sapin
rust: Remove handling of `parents` in `DirstateMap`...
r47891 dirstate::EntryState,
dirstate: move the handling of special case within the dirstatemap...
r48310 dirstate::MTIME_UNSET,
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 dirstate::SIZE_FROM_OTHER_PARENT,
dirstate::SIZE_NON_NORMAL,
dirstate: move the handling of special case within the dirstatemap...
r48310 dirstate::V1_RANGEMASK,
Raphaël Gomès
rust-utils: add normalize_case util to mirror Python one...
r43108 pack_dirstate, parse_dirstate,
Simon Sapin
rust: Remove DirstateMap::file_fold_map...
r47879 utils::hg_path::{HgPath, HgPathBuf},
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 CopyMap, DirsMultiset, DirstateEntry, DirstateError, DirstateParents,
StateMap,
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 };
Raphaël Gomès
rust-dirstatemap: add #[timed] to dirstatemap read for comparison...
r46135 use micro_timer::timed;
Raphaël Gomès
rust-performance: introduce FastHashMap type alias for HashMap...
r44278 use std::collections::HashSet;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 use std::iter::FromIterator;
use std::ops::Deref;
#[derive(Default)]
pub struct DirstateMap {
state_map: StateMap,
pub copy_map: CopyMap,
pub dirs: Option<DirsMultiset>,
pub all_dirs: Option<DirsMultiset>,
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 non_normal_set: Option<HashSet<HgPathBuf>>,
other_parent_set: Option<HashSet<HgPathBuf>>,
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
/// Should only really be used in python interface code, for clarity
impl Deref for DirstateMap {
type Target = StateMap;
fn deref(&self) -> &Self::Target {
&self.state_map
}
}
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 impl FromIterator<(HgPathBuf, DirstateEntry)> for DirstateMap {
Raphaël Gomès
rust: format with rustfmt...
r46162 fn from_iter<I: IntoIterator<Item = (HgPathBuf, DirstateEntry)>>(
iter: I,
) -> Self {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 Self {
state_map: iter.into_iter().collect(),
..Self::default()
}
}
}
impl DirstateMap {
pub fn new() -> Self {
Self::default()
}
pub fn clear(&mut self) {
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 self.state_map = StateMap::default();
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 self.copy_map.clear();
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.non_normal_set = None;
self.other_parent_set = None;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 pub fn set_v1_inner(&mut self, filename: &HgPath, entry: DirstateEntry) {
self.state_map.insert(filename.to_owned(), entry);
}
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 /// Add a tracked file to the dirstate
pub fn add_file(
&mut self,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 filename: &HgPath,
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 entry: DirstateEntry,
dirstate: move the handling of special case within the dirstatemap...
r48310 // XXX once the dust settle this should probably become an enum
dirstate: use a `added` parameter to _addpath...
r48314 added: bool,
dirstate: use a `merged` parameter to _addpath...
r48316 merged: bool,
dirstate: move the handling of special case within the dirstatemap...
r48310 from_p2: bool,
possibly_dirty: bool,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 ) -> Result<(), DirstateError> {
dirstate: move the handling of special case within the dirstatemap...
r48310 let mut entry = entry;
dirstate: use a `added` parameter to _addpath...
r48314 if added {
dirstate: use a `merged` parameter to _addpath...
r48316 assert!(!merged);
dirstate: move the handling of special case within the dirstatemap...
r48310 assert!(!possibly_dirty);
assert!(!from_p2);
dirstate: use a `added` parameter to _addpath...
r48314 entry.state = EntryState::Added;
dirstate: move the handling of special case within the dirstatemap...
r48310 entry.size = SIZE_NON_NORMAL;
entry.mtime = MTIME_UNSET;
dirstate: use a `merged` parameter to _addpath...
r48316 } else if merged {
assert!(!possibly_dirty);
assert!(!from_p2);
entry.state = EntryState::Merged;
entry.size = SIZE_FROM_OTHER_PARENT;
entry.mtime = MTIME_UNSET;
dirstate: move the handling of special case within the dirstatemap...
r48310 } else if from_p2 {
assert!(!possibly_dirty);
dirstate: infer the 'n' state from `from_p2`...
r48318 entry.state = EntryState::Normal;
dirstate: move the handling of special case within the dirstatemap...
r48310 entry.size = SIZE_FROM_OTHER_PARENT;
entry.mtime = MTIME_UNSET;
} else if possibly_dirty {
dirstate: infer the 'n' state from `possibly_dirty`...
r48317 entry.state = EntryState::Normal;
dirstate: move the handling of special case within the dirstatemap...
r48310 entry.size = SIZE_NON_NORMAL;
entry.mtime = MTIME_UNSET;
} else {
dirstate: drop `state` to `_addpath`...
r48319 entry.state = EntryState::Normal;
dirstate: move the handling of special case within the dirstatemap...
r48310 entry.size = entry.size & V1_RANGEMASK;
entry.mtime = entry.mtime & V1_RANGEMASK;
}
dirstate: no longer pass the `oldstate` value to the dirstatemap...
r48313 let old_state = match self.get(filename) {
Some(e) => e.state,
None => EntryState::Unknown,
};
Raphaël Gomès
rust: format with rustfmt...
r46162 if old_state == EntryState::Unknown || old_state == EntryState::Removed
{
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 if let Some(ref mut dirs) = self.dirs {
Raphaël Gomès
rust-dirs: address failing tests for `dirs` impl with a temporary fix...
r44227 dirs.add_path(filename)?;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
}
if old_state == EntryState::Unknown {
if let Some(ref mut all_dirs) = self.all_dirs {
Raphaël Gomès
rust-dirs: address failing tests for `dirs` impl with a temporary fix...
r44227 all_dirs.add_path(filename)?;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
}
self.state_map.insert(filename.to_owned(), entry.to_owned());
Simon Sapin
dirstate-tree: Add "non normal" and "from other parent" sets...
r47878 if entry.is_non_normal() {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.0
.insert(filename.to_owned());
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Simon Sapin
dirstate-tree: Add "non normal" and "from other parent" sets...
r47878 if entry.is_from_other_parent() {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.1
.insert(filename.to_owned());
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust-dirs: address failing tests for `dirs` impl with a temporary fix...
r44227 Ok(())
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
/// Mark a file as removed in the dirstate.
///
/// The `size` parameter is used to store sentinel values that indicate
/// the file's previous state. In the future, we should refactor this
/// to be more explicit about what that state is.
pub fn remove_file(
&mut self,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 filename: &HgPath,
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 in_merge: bool,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 ) -> Result<(), DirstateError> {
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 let old_entry_opt = self.get(filename);
let old_state = match old_entry_opt {
Some(e) => e.state,
None => EntryState::Unknown,
};
let mut size = 0;
if in_merge {
// XXX we should not be able to have 'm' state and 'FROM_P2' if not
// during a merge. So I (marmoute) am not sure we need the
// conditionnal at all. Adding double checking this with assert
// would be nice.
if let Some(old_entry) = old_entry_opt {
// backup the previous state
if old_entry.state == EntryState::Merged {
size = SIZE_NON_NORMAL;
} else if old_entry.state == EntryState::Normal
&& old_entry.size == SIZE_FROM_OTHER_PARENT
{
// other parent
size = SIZE_FROM_OTHER_PARENT;
self.get_non_normal_other_parent_entries()
.1
.insert(filename.to_owned());
}
}
}
Raphaël Gomès
rust: format with rustfmt...
r46162 if old_state != EntryState::Unknown && old_state != EntryState::Removed
{
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 if let Some(ref mut dirs) = self.dirs {
dirs.delete_path(filename)?;
}
}
if old_state == EntryState::Unknown {
if let Some(ref mut all_dirs) = self.all_dirs {
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 all_dirs.add_path(filename)?;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
}
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 if size == 0 {
self.copy_map.remove(filename);
}
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
self.state_map.insert(
filename.to_owned(),
DirstateEntry {
state: EntryState::Removed,
mode: 0,
size,
mtime: 0,
},
);
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.0
.insert(filename.to_owned());
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 Ok(())
}
/// Remove a file from the dirstate.
/// Returns `true` if the file was previously recorded.
pub fn drop_file(
&mut self,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 filename: &HgPath,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 ) -> Result<bool, DirstateError> {
dirstate: no longer pass `oldstate` to the `dropfile`...
r48324 let old_state = match self.get(filename) {
Some(e) => e.state,
None => EntryState::Unknown,
};
Yuya Nishihara
rust-dirstate: remove too abstracted way of getting &[u8]
r43063 let exists = self.state_map.remove(filename).is_some();
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
if exists {
if old_state != EntryState::Removed {
if let Some(ref mut dirs) = self.dirs {
dirs.delete_path(filename)?;
}
}
if let Some(ref mut all_dirs) = self.all_dirs {
all_dirs.delete_path(filename)?;
}
}
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.0
.remove(filename);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
Ok(exists)
}
Raphaël Gomès
rust: format with rustfmt...
r46162 pub fn clear_ambiguous_times(
&mut self,
filenames: Vec<HgPathBuf>,
now: i32,
) {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 for filename in filenames {
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 if let Some(entry) = self.state_map.get_mut(&filename) {
Simon Sapin
dirstate-tree: Remove DirstateMap::iter_node_data_mut...
r48121 if entry.clear_ambiguous_mtime(now) {
Simon Sapin
dirstate-tree: Add clear_ambiguous_times in the new DirstateMap...
r47875 self.get_non_normal_other_parent_entries()
.0
.insert(filename.to_owned());
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 }
}
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
}
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 pub fn non_normal_entries_remove(
&mut self,
key: impl AsRef<HgPath>,
) -> bool {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.0
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 .remove(key.as_ref())
}
pub fn non_normal_entries_add(&mut self, key: impl AsRef<HgPath>) {
self.get_non_normal_other_parent_entries()
.0
.insert(key.as_ref().into());
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 }
Simon Sapin
dirstate-tree: Add "non normal" and "from other parent" sets...
r47878
Raphaël Gomès
rust: format with rustfmt...
r46162 pub fn non_normal_entries_union(
&mut self,
other: HashSet<HgPathBuf>,
) -> Vec<HgPathBuf> {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.get_non_normal_other_parent_entries()
.0
.union(&other)
Raphaël Gomès
rust: do a clippy pass...
r45500 .map(ToOwned::to_owned)
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 .collect()
}
pub fn get_non_normal_other_parent_entries(
&mut self,
Raphaël Gomès
rust-dirstatemap: directly return `non_normal` and `other_entries`...
r44842 ) -> (&mut HashSet<HgPathBuf>, &mut HashSet<HgPathBuf>) {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.set_non_normal_other_parent_entries(false);
Raphaël Gomès
rust-dirstatemap: directly return `non_normal` and `other_entries`...
r44842 (
self.non_normal_set.as_mut().unwrap(),
self.other_parent_set.as_mut().unwrap(),
)
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 }
Raphaël Gomès
rust-cpython: make `NonNormalEntires` iterable to fix `fsmonitor` (issue6276)...
r44903 /// Useful to get immutable references to those sets in contexts where
/// you only have an immutable reference to the `DirstateMap`, like when
/// sharing references with Python.
///
/// TODO, get rid of this along with the other "setter/getter" stuff when
/// a nice typestate plan is defined.
///
/// # Panics
///
/// Will panic if either set is `None`.
pub fn get_non_normal_other_parent_entries_panic(
&self,
) -> (&HashSet<HgPathBuf>, &HashSet<HgPathBuf>) {
(
self.non_normal_set.as_ref().unwrap(),
self.other_parent_set.as_ref().unwrap(),
)
}
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 pub fn set_non_normal_other_parent_entries(&mut self, force: bool) {
Raphaël Gomès
rust: format with rustfmt...
r46162 if !force
&& self.non_normal_set.is_some()
&& self.other_parent_set.is_some()
{
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 return;
}
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 let mut non_normal = HashSet::new();
let mut other_parent = HashSet::new();
Simon Sapin
dirstate-tree: Add "non normal" and "from other parent" sets...
r47878 for (filename, entry) in self.state_map.iter() {
if entry.is_non_normal() {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 non_normal.insert(filename.to_owned());
}
Simon Sapin
dirstate-tree: Add "non normal" and "from other parent" sets...
r47878 if entry.is_from_other_parent() {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 other_parent.insert(filename.to_owned());
}
}
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.non_normal_set = Some(non_normal);
self.other_parent_set = Some(other_parent);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
/// Both of these setters and their uses appear to be the simplest way to
/// emulate a Python lazy property, but it is ugly and unidiomatic.
/// TODO One day, rewriting this struct using the typestate might be a
/// good idea.
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 pub fn set_all_dirs(&mut self) -> Result<(), DirstateError> {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 if self.all_dirs.is_none() {
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 self.all_dirs = Some(DirsMultiset::from_dirstate(
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 self.state_map.iter().map(|(k, v)| Ok((k, *v))),
pathutil: replace the `skip` argument of `dirs` with a boolean...
r48756 false,
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 )?);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 Ok(())
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 pub fn set_dirs(&mut self) -> Result<(), DirstateError> {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 if self.dirs.is_none() {
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 self.dirs = Some(DirsMultiset::from_dirstate(
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 self.state_map.iter().map(|(k, v)| Ok((k, *v))),
pathutil: replace the `skip` argument of `dirs` with a boolean...
r48756 true,
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 )?);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 Ok(())
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust: format with rustfmt...
r46162 pub fn has_tracked_dir(
&mut self,
directory: &HgPath,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 ) -> Result<bool, DirstateError> {
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 self.set_dirs()?;
Ok(self.dirs.as_ref().unwrap().contains(directory))
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust: format with rustfmt...
r46162 pub fn has_dir(
&mut self,
directory: &HgPath,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 ) -> Result<bool, DirstateError> {
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 self.set_all_dirs()?;
Ok(self.all_dirs.as_ref().unwrap().contains(directory))
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
Raphaël Gomès
rust-dirstatemap: add #[timed] to dirstatemap read for comparison...
r46135 #[timed]
Simon Sapin
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer...
r47893 pub fn read(
Raphaël Gomès
rust: format with rustfmt...
r46162 &mut self,
Simon Sapin
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer...
r47893 file_contents: &[u8],
) -> Result<Option<DirstateParents>, DirstateError> {
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 if file_contents.is_empty() {
return Ok(None);
}
Antoine Cezar
hg-core: make parse_dirstate return references rather than update hashmaps...
r45916 let (parents, entries, copies) = parse_dirstate(file_contents)?;
self.state_map.extend(
entries
.into_iter()
.map(|(path, entry)| (path.to_owned(), entry)),
);
self.copy_map.extend(
copies
.into_iter()
.map(|(path, copy)| (path.to_owned(), copy.to_owned())),
);
Simon Sapin
dirstate-tree: Make `DirstateMap` borrow from a bytes buffer...
r47893 Ok(Some(parents.clone()))
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
pub fn pack(
&mut self,
parents: DirstateParents,
Simon Sapin
rust: Add a Timestamp struct instead of abusing Duration...
r47871 now: Timestamp,
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 ) -> Result<Vec<u8>, DirstateError> {
Raphaël Gomès
rust: format with rustfmt...
r46162 let packed =
pack_dirstate(&mut self.state_map, &self.copy_map, parents, now)?;
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 self.set_non_normal_other_parent_entries(true);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 Ok(packed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dirs_multiset() {
let mut map = DirstateMap::new();
assert!(map.dirs.is_none());
assert!(map.all_dirs.is_none());
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 assert_eq!(map.has_dir(HgPath::new(b"nope")).unwrap(), false);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 assert!(map.all_dirs.is_some());
assert!(map.dirs.is_none());
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 assert_eq!(map.has_tracked_dir(HgPath::new(b"nope")).unwrap(), false);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 assert!(map.dirs.is_some());
}
#[test]
fn test_add_file() {
let mut map = DirstateMap::new();
assert_eq!(0, map.len());
map.add_file(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPath::new(b"meh"),
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 DirstateEntry {
state: EntryState::Normal,
mode: 1337,
mtime: 1337,
size: 1337,
},
dirstate: move the handling of special case within the dirstatemap...
r48310 false,
false,
dirstate: use a `added` parameter to _addpath...
r48314 false,
dirstate: use a `merged` parameter to _addpath...
r48316 false,
Raphaël Gomès
rust-warnings: fix warnings in tests...
r44342 )
.unwrap();
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
assert_eq!(1, map.len());
Raphaël Gomès
rust-dirstatemap: directly return `non_normal` and `other_entries`...
r44842 assert_eq!(0, map.get_non_normal_other_parent_entries().0.len());
assert_eq!(0, map.get_non_normal_other_parent_entries().1.len());
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
#[test]
fn test_non_normal_other_parent_entries() {
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 let mut map: DirstateMap = [
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 (b"f1", (EntryState::Removed, 1337, 1337, 1337)),
(b"f2", (EntryState::Normal, 1337, 1337, -1)),
(b"f3", (EntryState::Normal, 1337, 1337, 1337)),
(b"f4", (EntryState::Normal, 1337, -2, 1337)),
(b"f5", (EntryState::Added, 1337, 1337, 1337)),
(b"f6", (EntryState::Added, 1337, 1337, -1)),
(b"f7", (EntryState::Merged, 1337, 1337, -1)),
(b"f8", (EntryState::Merged, 1337, 1337, 1337)),
(b"f9", (EntryState::Merged, 1337, -2, 1337)),
(b"fa", (EntryState::Added, 1337, -2, 1337)),
(b"fb", (EntryState::Removed, 1337, -2, 1337)),
]
.iter()
.map(|(fname, (state, mode, size, mtime))| {
(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPathBuf::from_bytes(fname.as_ref()),
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 DirstateEntry {
state: *state,
mode: *mode,
size: *size,
mtime: *mtime,
},
)
})
.collect();
Raphaël Gomès
rust-dirstatemap: directly return `non_normal` and `other_entries`...
r44842 let mut non_normal = [
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 b"f1", b"f2", b"f5", b"f6", b"f7", b"f8", b"f9", b"fa", b"fb",
]
.iter()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .map(|x| HgPathBuf::from_bytes(x.as_ref()))
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 .collect();
let mut other_parent = HashSet::new();
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 other_parent.insert(HgPathBuf::from_bytes(b"f4"));
Raphaël Gomès
rust-dirstatemap: cache non normal and other parent set...
r44775 let entries = map.get_non_normal_other_parent_entries();
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998
Raphaël Gomès
rust: format with rustfmt...
r46162 assert_eq!(
(&mut non_normal, &mut other_parent),
(entries.0, entries.1)
);
Raphaël Gomès
rust-dirstate: rust implementation of dirstatemap...
r42998 }
}