##// END OF EJS Templates
dirstate: add a synchronisation point before doing a full dirstate read...
dirstate: add a synchronisation point before doing a full dirstate read This will be useful to test some race conditions around the dirstate.

File last commit:

r51117:ecd28d89 stable
r51123:fc8e37c3 stable
Show More
dirstate_map.rs
551 lines | 17.9 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 };
Raphaël Gomès
rust-dirstatemap: add Rust implementation of `reset_state`...
r49992 use hg::dirstate::{ParentFileData, TruncatedTimestamp};
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999
use crate::{
dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
dirstate: remove need_delay logic...
r49221 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::{
dirstate: use more than a bool to control append behavior...
r51116 dirstate::StateMapIter, dirstate_tree::dirstate_map::DirstateMapWriteMode,
dirstate_tree::on_disk::DirstateV2ParseError,
Raphaël Gomès
rust-dirstatemap: use `&HgPath` instead of `HgPathBuf` in `copy_map_insert`...
r50015 dirstate_tree::owning::OwningDirstateMap, revlog::Node,
utils::files::normalize_case, utils::hg_path::HgPath, DirstateEntry,
Raphaël Gomès
rust-hg-cpython: remove use of `EntryState`...
r50026 DirstateError, DirstateParents,
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);
Raphaël Gomès
rust: fix unsound `OwningDirstateMap`...
r49864 let (map, parents) = OwningDirstateMap::new_v1(on_disk)
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 .map_err(|e| dirstate_error(py, e))?;
Simon Sapin
dirstate: Remove the Rust abstraction DirstateMapMethods...
r48883 let map = Self::create_instance(py, map)?;
Raphaël Gomès
rust: fix unsound `OwningDirstateMap`...
r49864 let p1 = PyBytes::new(py, parents.p1.as_bytes());
let p2 = PyBytes::new(py, parents.p2.as_bytes());
let parents = (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);
Raphaël Gomès
rust: fix unsound `OwningDirstateMap`...
r49864 let map = OwningDirstateMap::new_v2(
Simon Sapin
rust: Make OwningDirstateMap generic and move it into hg-core...
r48766 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)
}
}
Raphaël Gomès
dirstatemap: move `set_tracked` out of common methods and plug in Rust...
r49989 def set_tracked(&self, f: PyObject) -> PyResult<PyBool> {
let bytes = f.extract::<PyBytes>(py)?;
let path = HgPath::new(bytes.data(py));
let res = self.inner(py).borrow_mut().set_tracked(path);
let was_tracked = res.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))
})?;
Ok(was_tracked.to_py_object(py))
}
Raphaël Gomès
rust-dirstatemap: add `set_untracked` method...
r49999 def set_untracked(&self, f: PyObject) -> PyResult<PyBool> {
let bytes = f.extract::<PyBytes>(py)?;
let path = HgPath::new(bytes.data(py));
let res = self.inner(py).borrow_mut().set_untracked(path);
let was_tracked = res.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))
})?;
Ok(was_tracked.to_py_object(py))
dirstate-map: move most of `dirstate.update_file` logic in the dsmap...
r48492 }
Raphaël Gomès
rust-dirstatemap: add `set_clean` method...
r49995 def set_clean(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 &self,
Raphaël Gomès
rust-dirstatemap: add `set_clean` method...
r49995 f: PyObject,
mode: u32,
size: u32,
mtime: (i64, u32, bool)
Simon Sapin
dirstate: Pass the final DirstateItem to _rustmap.addfile()...
r48865 ) -> PyResult<PyNone> {
Raphaël Gomès
rust-dirstatemap: add `set_clean` method...
r49995 let (mtime_s, mtime_ns, second_ambiguous) = mtime;
let timestamp = TruncatedTimestamp::new_truncate(
mtime_s, mtime_ns, second_ambiguous
);
let bytes = f.extract::<PyBytes>(py)?;
let path = HgPath::new(bytes.data(py));
let res = self.inner(py).borrow_mut().set_clean(
path, mode, size, timestamp,
);
res.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))
})?;
Simon Sapin
dirstate: Pass the final DirstateItem to _rustmap.addfile()...
r48865 Ok(PyNone)
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Raphaël Gomès
rust-dirstatemap: add `set_possibly_dirty` method...
r49997 def set_possibly_dirty(&self, f: PyObject) -> PyResult<PyNone> {
let bytes = f.extract::<PyBytes>(py)?;
let path = HgPath::new(bytes.data(py));
let res = self.inner(py).borrow_mut().set_possibly_dirty(path);
res.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))
})?;
Ok(PyNone)
}
Raphaël Gomès
rust-dirstatemap: add Rust implementation of `reset_state`...
r49992 def reset_state(
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 &self,
f: PyObject,
Raphaël Gomès
rust-dirstatemap: add Rust implementation of `reset_state`...
r49992 wc_tracked: bool,
p1_tracked: bool,
p2_info: bool,
has_meaningful_mtime: bool,
parentfiledata: Option<(u32, u32, Option<(i64, u32, bool)>)>,
Simon Sapin
dirstate: Remove return boolean from dirstatemap.dropfile...
r48862 ) -> PyResult<PyNone> {
Raphaël Gomès
rust-dirstatemap: add Rust implementation of `reset_state`...
r49992 let mut has_meaningful_mtime = has_meaningful_mtime;
let parent_file_data = match parentfiledata {
None => {
has_meaningful_mtime = false;
None
},
Some(data) => {
let (mode, size, mtime_info) = data;
let mtime = if let Some(mtime_info) = mtime_info {
let (mtime_s, mtime_ns, second_ambiguous) = mtime_info;
let timestamp = TruncatedTimestamp::new_truncate(
mtime_s, mtime_ns, second_ambiguous
);
Some(timestamp)
} else {
has_meaningful_mtime = false;
None
};
Some(ParentFileData {
mode_size: Some((mode, size)),
mtime,
})
}
};
let bytes = f.extract::<PyBytes>(py)?;
let path = HgPath::new(bytes.data(py));
let res = self.inner(py).borrow_mut().reset_state(
path,
wc_tracked,
p1_tracked,
p2_info,
has_meaningful_mtime,
parent_file_data,
);
res.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))
})?;
Simon Sapin
dirstate: Remove return boolean from dirstatemap.dropfile...
r48862 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
rust: Serializing a DirstateMap does not mutate it anymore...
r49244 let inner = self.inner(py).borrow();
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 };
dirstate: remove need_delay logic...
r49221 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,
dirstate: use more than a bool to control append behavior...
r51116 write_mode: usize,
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 ) -> PyResult<PyObject> {
Simon Sapin
rust: Serializing a DirstateMap does not mutate it anymore...
r49244 let inner = self.inner(py).borrow();
dirstate: use more than a bool to control append behavior...
r51116 let rust_write_mode = match write_mode {
0 => DirstateMapWriteMode::Auto,
1 => DirstateMapWriteMode::ForceNewDataFile,
Raphaël Gomès
dirstate-v2: add devel config option to control write behavior...
r51117 2 => DirstateMapWriteMode::ForceAppend,
dirstate: use more than a bool to control append behavior...
r51116 _ => DirstateMapWriteMode::Auto, // XXX should we error out?
};
let result = inner.pack_v2(rust_write_mode);
Simon Sapin
dirstate-v2: Change the on-disk format when the requirement is enabled...
r48055 match result {
Raphaël Gomès
rust-dirstate-v2: save proper data size if no new data on append...
r50037 Ok((packed, tree_metadata, append, _old_data_size)) => {
Simon Sapin
dirstate-v2: Support appending to the same data file...
r48478 let packed = PyBytes::new(py, &packed);
Simon Sapin
rhg: Add Repo::write_dirstate...
r49249 let tree_metadata = PyBytes::new(py, tree_metadata.as_bytes());
Simon Sapin
dirstate-v2: Move fixed-size tree metadata into the docket file...
r48482 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))?;
Raphaël Gomès
rust-hg-cpython: remove use of `EntryState`...
r50026 if !entry.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(
Raphaël Gomès
rust-dirstatemap: use `&HgPath` instead of `HgPathBuf` in `copy_map_insert`...
r50015 HgPath::new(key.data(py)),
HgPath::new(value.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-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)
}
Raphaël Gomès
rust-dirstatemap: implement part of the `setparents` logic...
r50011 def setparents_fixup(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
let copies = self.inner(py).borrow_mut().setparents_fixup();
for (key, value) in copies.map_err(|e| v2_error(py, e))? {
dict.set_item(
py,
PyBytes::new(py, key.as_bytes()),
PyBytes::new(py, value.as_bytes()),
)?;
}
Ok(dict)
}
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))
}