##// END OF EJS Templates
dirstate: remove need_delay logic...
dirstate: remove need_delay logic Now that all¹ stored mtime are non ambiguous, we no longer need to apply the `need_delay` step. The need delay logic was not great are mtime gathered during longer operation could be ambiguous but younger than the `dirstate.write` call time. So, we don't need that logic anymore and can drop it This make the code much simpler. The code related to the test extension faking the dirstate write is now obsolete and associated test will be migrated as follow up. They currently do not break. [1] except the ones from `hg update`, but `need_delay` no longer help for them either. Differential Revision: https://phab.mercurial-scm.org/D11796

File last commit:

r49215:2b5d1618 default
r49215:2b5d1618 default
Show More
dirstate_map.rs
499 lines | 15.7 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 // 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.
//! Bindings for the `hg::dirstate::dirstate_map` file provided by the
//! `hg-core` package.
Simon Sapin
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`...
r47882 use std::cell::{RefCell, RefMut};
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 use std::convert::TryInto;
use cpython::{
dirstate: drop the `clearambiguoustimes` method for the map...
r48870 exc, PyBool, PyBytes, PyClone, PyDict, PyErr, PyList, PyNone, PyObject,
dirstate: drop all logic around the "non-normal" sets...
r48875 PyResult, Python, PythonObject, ToPyObject, UnsafePyLeaked,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 };
use crate::{
dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
Raphaël Gomès
dirstate: remove need_delay logic...
r49215 dirstate::item::DirstateItem,
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 pybytes_deref::PyBytesDeref,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 };
use hg::{
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 dirstate::StateMapIter,
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 dirstate_tree::dirstate_map::DirstateMap as TreeDirstateMap,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 dirstate_tree::on_disk::DirstateV2ParseError,
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 dirstate_tree::owning::OwningDirstateMap,
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 revlog::Node,
Simon Sapin
rust: Remove DirstateMap::file_fold_map...
r47879 utils::files::normalize_case,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 utils::hg_path::{HgPath, HgPathBuf},
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 DirstateEntry, DirstateError, DirstateParents, EntryState,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 };
// TODO
// This object needs to share references to multiple members of its Rust
// inner struct, namely `copy_map`, `dirs` and `all_dirs`.
// Right now `CopyMap` is done, but it needs to have an explicit reference
// to `RustDirstateMap` which itself needs to have an encapsulation for
// every method in `CopyMap` (copymapcopy, etc.).
// This is ugly and hard to maintain.
// The same logic applies to `dirs` and `all_dirs`, however the `Dirs`
// `py_class!` is already implemented and does not mention
// `RustDirstateMap`, rightfully so.
// All attributes also have to have a separate refcount data attribute for
// leaks, with all methods that go along for reference sharing.
py_class!(pub class DirstateMap |py| {
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 @shared data inner: OwningDirstateMap;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999
Simon Sapin
rust: Read dirstate from disk in DirstateMap constructor...
r47892 /// Returns a `(dirstate_map, parents)` tuple
@staticmethod
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 def new_v1(
Simon Sapin
dirstate-v2: Change the on-disk format when the requirement is enabled...
r48055 on_disk: PyBytes,
) -> PyResult<PyObject> {
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 let on_disk = PyBytesDeref::new(py, on_disk);
let mut map = OwningDirstateMap::new_empty(on_disk);
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 let (on_disk, map_placeholder) = map.get_pair_mut();
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 let (actual_map, parents) = TreeDirstateMap::new_v1(on_disk)
.map_err(|e| dirstate_error(py, e))?;
*map_placeholder = actual_map;
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 let map = Self::create_instance(py, map)?;
Simon Sapin
rust: Remove the `rustext.parsers` module...
r48832 let parents = parents.map(|p| {
let p1 = PyBytes::new(py, p.p1.as_bytes());
let p2 = PyBytes::new(py, p.p2.as_bytes());
(p1, p2)
});
Simon Sapin
rust: Read dirstate from disk in DirstateMap constructor...
r47892 Ok((map, parents).to_py_object(py).into_object())
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 /// Returns a DirstateMap
@staticmethod
def new_v2(
on_disk: PyBytes,
Simon Sapin
dirstate-v2: Enforce data size read from the docket file...
r48475 data_size: usize,
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 tree_metadata: PyBytes,
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 ) -> PyResult<PyObject> {
let dirstate_error = |e: DirstateError| {
PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
};
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 let on_disk = PyBytesDeref::new(py, on_disk);
let mut map = OwningDirstateMap::new_empty(on_disk);
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 let (on_disk, map_placeholder) = map.get_pair_mut();
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 *map_placeholder = TreeDirstateMap::new_v2(
on_disk, data_size, tree_metadata.data(py),
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 ).map_err(dirstate_error)?;
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 let map = Self::create_instance(py, map)?;
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 Ok(map.into_object())
}
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 def clear(&self) -> PyResult<PyObject> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 self.inner(py).borrow_mut().clear();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Ok(py.None())
}
def get(
&self,
key: PyObject,
default: Option<PyObject> = None
) -> PyResult<Option<PyObject>> {
let key = key.extract::<PyBytes>(py)?;
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 match self
.inner(py)
.borrow()
.get(HgPath::new(key.data(py)))
.map_err(|e| v2_error(py, e))?
{
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Some(entry) => {
Simon Sapin
dirstate: Use the Rust implementation of DirstateItem when Rust is enabled...
r48858 Ok(Some(DirstateItem::new_as_pyobject(py, entry)?))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 },
None => Ok(default)
}
}
Simon Sapin
dirstate: Skip no-op conversion in Rust DirstateMap::set_v1...
r48859 def set_dirstate_item(
&self,
path: PyObject,
item: DirstateItem
) -> PyResult<PyObject> {
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 let f = path.extract::<PyBytes>(py)?;
let filename = HgPath::new(f.data(py));
Simon Sapin
dirstate: Propagate dirstate-v2 parse errors from set_dirstate_item...
r48861 self.inner(py)
.borrow_mut()
.set_entry(filename, item.get_entry(py))
.map_err(|e| v2_error(py, e))?;
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 Ok(py.None())
}
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 def addfile(
&self,
Simon Sapin
dirstate: Pass the final DirstateItem to _rustmap.addfile()...
r48865 f: PyBytes,
item: DirstateItem,
) -> PyResult<PyNone> {
rust-dirstatemap: expand the wrapping code a bit...
r48307 let filename = HgPath::new(f.data(py));
Simon Sapin
dirstate: Pass the final DirstateItem to _rustmap.addfile()...
r48865 let entry = item.get_entry(py);
self.inner(py)
.borrow_mut()
.add_file(filename, entry)
.map_err(|e |dirstate_error(py, e))?;
Ok(PyNone)
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def removefile(
&self,
f: PyObject,
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 in_merge: PyObject
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 ) -> PyResult<PyObject> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 self.inner(py).borrow_mut()
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .remove_file(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
dirstate: move most of the `remove` logic with dirstatemap `removefile`...
r48300 in_merge.extract::<PyBool>(py)?.is_true(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
))
})?;
Ok(py.None())
}
Simon Sapin
dirstate: Replace dropfile with drop_item_and_copy_source...
r48864 def drop_item_and_copy_source(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 &self,
Simon Sapin
dirstate: Remove return boolean from dirstatemap.dropfile...
r48862 f: PyBytes,
) -> PyResult<PyNone> {
self.inner(py)
.borrow_mut()
Simon Sapin
dirstate: Replace dropfile with drop_item_and_copy_source...
r48864 .drop_entry_and_copy_source(HgPath::new(f.data(py)))
Simon Sapin
dirstate: Remove return boolean from dirstatemap.dropfile...
r48862 .map_err(|e |dirstate_error(py, e))?;
Ok(PyNone)
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
let d = d.extract::<PyBytes>(py)?;
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 Ok(self.inner(py).borrow_mut()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .has_tracked_dir(HgPath::new(d.data(py)))
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 .map_err(|e| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .to_py_object(py))
}
def hasdir(&self, d: PyObject) -> PyResult<PyBool> {
let d = d.extract::<PyBytes>(py)?;
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 Ok(self.inner(py).borrow_mut()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .has_dir(HgPath::new(d.data(py)))
Raphaël Gomès
rust-dirs: handle forgotten `Result`s...
r44315 .map_err(|e| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .to_py_object(py))
}
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 def write_v1(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 &self,
p1: PyObject,
p2: PyObject,
) -> PyResult<PyBytes> {
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 let mut inner = self.inner(py).borrow_mut();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 let parents = DirstateParents {
Yuya Nishihara
rust-dirstate: handle invalid length of p1/p2 parameters...
r43068 p1: extract_node_id(py, &p1)?,
p2: extract_node_id(py, &p2)?,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 };
Raphaël Gomès
dirstate: remove need_delay logic...
r49215 let result = inner.pack_v1(parents);
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 match result {
Ok(packed) => Ok(PyBytes::new(py, &packed)),
Err(_) => Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
)),
}
}
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 /// Returns new data together with whether that data should be appended to
/// the existing data file whose content is at `self.on_disk` (True),
/// instead of written to a new data file (False).
Simon Sapin
dirstate-v2: Introduce a docket file...
r48474 def write_v2(
&self,
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 can_append: bool,
) -> PyResult<PyObject> {
Simon Sapin
dirstate-v2: Change the on-disk format when the requirement is enabled...
r48055 let mut inner = self.inner(py).borrow_mut();
Raphaël Gomès
dirstate: remove need_delay logic...
r49215 let result = inner.pack_v2(can_append);
Simon Sapin
dirstate-v2: Change the on-disk format when the requirement is enabled...
r48055 match result {
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 Ok((packed, tree_metadata, append)) => {
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 let packed = PyBytes::new(py, &packed);
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 let tree_metadata = PyBytes::new(py, &tree_metadata);
let tuple = (packed, tree_metadata, append);
Ok(tuple.to_py_object(py).into_object())
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Err(_) => Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
)),
}
}
def filefoldmapasdict(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 for item in self.inner(py).borrow_mut().iter() {
let (path, entry) = item.map_err(|e| v2_error(py, e))?;
Simon Sapin
rust: Make the fields of DirstateEntry private...
r48834 if entry.state() != EntryState::Removed {
Simon Sapin
rust: Remove DirstateMap::file_fold_map...
r47879 let key = normalize_case(path);
let value = path;
dict.set_item(
py,
PyBytes::new(py, key.as_bytes()).into_object(),
PyBytes::new(py, value.as_bytes()).into_object(),
)?;
}
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Ok(dict)
}
def __len__(&self) -> PyResult<usize> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 Ok(self.inner(py).borrow().len())
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def __contains__(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 self.inner(py)
.borrow()
.contains_key(HgPath::new(key.data(py)))
.map_err(|e| v2_error(py, e))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
let key = key.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let key = HgPath::new(key.data(py));
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 match self
.inner(py)
.borrow()
.get(key)
.map_err(|e| v2_error(py, e))?
{
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Some(entry) => {
Simon Sapin
dirstate: Use the Rust implementation of DirstateItem when Rust is enabled...
r48858 Ok(DirstateItem::new_as_pyobject(py, entry)?)
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 },
None => Err(PyErr::new::<exc::KeyError, _>(
py,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 String::from_utf8_lossy(key.as_bytes()),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )),
}
}
def keys(&self) -> PyResult<DirstateMapKeysIterator> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 let leaked_ref = self.inner(py).leak_immutable();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapKeysIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: make PyLeakedRef operations relatively safe...
r43579 unsafe { leaked_ref.map(py, |o| o.iter()) },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def items(&self) -> PyResult<DirstateMapItemsIterator> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 let leaked_ref = self.inner(py).leak_immutable();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapItemsIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: make PyLeakedRef operations relatively safe...
r43579 unsafe { leaked_ref.map(py, |o| o.iter()) },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 let leaked_ref = self.inner(py).leak_immutable();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapKeysIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: make PyLeakedRef operations relatively safe...
r43579 unsafe { leaked_ref.map(py, |o| o.iter()) },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
// TODO all copymap* methods, see docstring above
def copymapcopy(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 for item in self.inner(py).borrow().copy_map_iter() {
let (key, value) = item.map_err(|e| v2_error(py, e))?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 dict.set_item(
py,
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, key.as_bytes()),
PyBytes::new(py, value.as_bytes()),
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 )?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Ok(dict)
}
def copymapgetitem(&self, key: PyObject) -> PyResult<PyBytes> {
let key = key.extract::<PyBytes>(py)?;
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 match self
.inner(py)
.borrow()
.copy_map_get(HgPath::new(key.data(py)))
.map_err(|e| v2_error(py, e))?
{
Raphaël Gomès
rust: do a clippy pass...
r45500 Some(copy) => Ok(PyBytes::new(py, copy.as_bytes())),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 None => Err(PyErr::new::<exc::KeyError, _>(
py,
String::from_utf8_lossy(key.data(py)),
)),
}
}
def copymap(&self) -> PyResult<CopyMap> {
CopyMap::from_inner(py, self.clone_ref(py))
}
def copymaplen(&self) -> PyResult<usize> {
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 Ok(self.inner(py).borrow().copy_map_len())
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 self.inner(py)
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .borrow()
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 .copy_map_contains_key(HgPath::new(key.data(py)))
.map_err(|e| v2_error(py, e))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
def copymapget(
&self,
key: PyObject,
default: Option<PyObject>
) -> PyResult<Option<PyObject>> {
let key = key.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 match self
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 .inner(py)
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .borrow()
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 .copy_map_get(HgPath::new(key.data(py)))
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 .map_err(|e| v2_error(py, e))?
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 {
Some(copy) => Ok(Some(
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, copy.as_bytes()).into_object(),
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 )),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 None => Ok(default),
}
}
def copymapsetitem(
&self,
key: PyObject,
value: PyObject
) -> PyResult<PyObject> {
let key = key.extract::<PyBytes>(py)?;
let value = value.extract::<PyBytes>(py)?;
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 self.inner(py)
.borrow_mut()
.copy_map_insert(
HgPathBuf::from_bytes(key.data(py)),
HgPathBuf::from_bytes(value.data(py)),
)
.map_err(|e| v2_error(py, e))?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Ok(py.None())
}
def copymappop(
&self,
key: PyObject,
default: Option<PyObject>
) -> PyResult<Option<PyObject>> {
let key = key.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 match self
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 .inner(py)
Yuya Nishihara
rust-cpython: add panicking version of borrow_mut() and use it...
r44685 .borrow_mut()
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 .copy_map_remove(HgPath::new(key.data(py)))
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 .map_err(|e| v2_error(py, e))?
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 {
dirstatemap: fix copymap.pop in Rust to return the value it pops...
r48947 Some(copy) => Ok(Some(
PyBytes::new(py, copy.as_bytes()).into_object(),
)),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 None => Ok(default),
}
}
def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 let leaked_ref = self.inner(py).leak_immutable();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 CopyMapKeysIterator::from_inner(
py,
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
Yuya Nishihara
rust-cpython: rename inner_shared() to inner()...
r44702 let leaked_ref = self.inner(py).leak_immutable();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 CopyMapItemsIterator::from_inner(
py,
Simon Sapin
dirstate-tree: Make Rust DirstateMap bindings go through a trait object...
r47863 unsafe { leaked_ref.map(py, |o| o.copy_map_iter()) },
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 def tracked_dirs(&self) -> PyResult<PyList> {
Simon Sapin
dirstate-v2: Add --dirs to debugdirstate command...
r48140 let dirs = PyList::new(py, &[]);
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 for path in self.inner(py).borrow_mut().iter_tracked_dirs()
.map_err(|e |dirstate_error(py, e))?
{
let path = path.map_err(|e| v2_error(py, e))?;
Simon Sapin
dirstate-v2: Add --dirs to debugdirstate command...
r48140 let path = PyBytes::new(py, path.as_bytes());
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 dirs.append(py, path.into_object())
Simon Sapin
dirstate-v2: Add --dirs to debugdirstate command...
r48140 }
Ok(dirs)
}
Simon Sapin
debugstate: Always call dirstatemap.debug_iter()...
r48835 def debug_iter(&self, all: bool) -> PyResult<PyList> {
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 let dirs = PyList::new(py, &[]);
Simon Sapin
debugstate: Always call dirstatemap.debug_iter()...
r48835 for item in self.inner(py).borrow().debug_iter(all) {
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 let (path, (state, mode, size, mtime)) =
item.map_err(|e| v2_error(py, e))?;
let path = PyBytes::new(py, path.as_bytes());
Simon Sapin
debugsate: Change debug_iter() to yield tuples instead of DirstateItem...
r48836 let item = (path, state, mode, size, mtime);
dirs.append(py, item.to_py_object(py).into_object())
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483 }
Ok(dirs)
}
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 });
impl DirstateMap {
Simon Sapin
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`...
r47882 pub fn get_inner_mut<'a>(
Raphaël Gomès
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
r43567 &'a self,
py: Python<'a>,
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 ) -> RefMut<'a, OwningDirstateMap> {
Simon Sapin
dirstate-tree: Give to `status()` mutable access to the `DirstateMap`...
r47882 self.inner(py).borrow_mut()
Raphaël Gomès
rust-dirstate-status: rust-cpython bindings for `dirstate.status`...
r43567 }
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 fn translate_key(
py: Python,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 ) -> PyResult<Option<PyBytes>> {
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 let (f, _entry) = res.map_err(|e| v2_error(py, e))?;
Ok(Some(PyBytes::new(py, f.as_bytes())))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
fn translate_key_value(
py: Python,
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 res: Result<(&HgPath, DirstateEntry), DirstateV2ParseError>,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 ) -> PyResult<Option<(PyBytes, PyObject)>> {
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126 let (f, entry) = res.map_err(|e| v2_error(py, e))?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Ok(Some((
Raphaël Gomès
rust: do a clippy pass...
r45500 PyBytes::new(py, f.as_bytes()),
Simon Sapin
dirstate: Use the Rust implementation of DirstateItem when Rust is enabled...
r48858 DirstateItem::new_as_pyobject(py, entry)?,
Raphaël Gomès
rust: start plugging the dirstate tree behind a feature gate...
r46185 )))
}
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Yuya Nishihara
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator...
r43159 py_shared_iterator!(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapKeysIterator,
Yuya Nishihara
rust-cpython: switch to upstreamed version of PySharedRefCell...
r44703 UnsafePyLeaked<StateMapIter<'static>>,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMap::translate_key,
Option<PyBytes>
);
Yuya Nishihara
rust-cpython: rename py_shared_iterator_impl to py_shared_iterator...
r43159 py_shared_iterator!(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapItemsIterator,
Yuya Nishihara
rust-cpython: switch to upstreamed version of PySharedRefCell...
r44703 UnsafePyLeaked<StateMapIter<'static>>,
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMap::translate_key_value,
Option<(PyBytes, PyObject)>
);
Yuya Nishihara
rust-dirstate: handle invalid length of p1/p2 parameters...
r43068
Simon Sapin
rust: Make `DirstateParents`’s fields typed `Node`s...
r47337 fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<Node> {
Yuya Nishihara
rust-dirstate: handle invalid length of p1/p2 parameters...
r43068 let bytes = obj.extract::<PyBytes>(py)?;
match bytes.data(py).try_into() {
Ok(s) => Ok(s),
Err(e) => Err(PyErr::new::<exc::ValueError, _>(py, e.to_string())),
}
}
Simon Sapin
dirstate-v2: Make more APIs fallible, returning Result...
r48126
pub(super) fn v2_error(py: Python<'_>, _: DirstateV2ParseError) -> PyErr {
PyErr::new::<exc::ValueError, _>(py, "corrupted dirstate-v2")
}
Simon Sapin
dirstate-v2: Separate iterators for dirfoldmap and debugdirstate...
r48483
fn dirstate_error(py: Python<'_>, e: DirstateError) -> PyErr {
PyErr::new::<exc::OSError, _>(py, format!("Dirstate error: {:?}", e))
}