##// END OF EJS Templates
unstable: do not consider internal phases when computing unstable...
unstable: do not consider internal phases when computing unstable The revisions that are not part of the "working" set by other means should not be considered for the evolution related computation. This impact the test introduced in 5f9af8422b31 as this is actually a more semantic fix of the issue.

File last commit:

r51147:a6b8b1ab merge default
r52017:80bda425 default
Show More
dirstate_map.rs
556 lines | 18.2 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 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,
Raphaël Gomès
rhg: remember the inode of .hg/dirstate...
r51140 identity: Option<u64>,
Simon Sapin
dirstate-v2: Change the on-disk format when the requirement is enabled...
r48055 ) -> PyResult<PyObject> {
Simon Sapin
dirstate: Remove the flat Rust DirstateMap implementation...
r48882 let on_disk = PyBytesDeref::new(py, on_disk);
Raphaël Gomès
rhg: remember the inode of .hg/dirstate...
r51140 let (map, parents) = OwningDirstateMap::new_v1(on_disk, identity)
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,
Raphaël Gomès
rust-dirstate: remember the data file uuid dirstate was loaded with...
r51138 uuid: PyBytes,
Raphaël Gomès
rhg: remember the inode of .hg/dirstate...
r51140 identity: Option<u64>,
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-dirstate: remember the data file uuid dirstate was loaded with...
r51138 let uuid = uuid.data(py);
Raphaël Gomès
rust: fix unsound `OwningDirstateMap`...
r49864 let map = OwningDirstateMap::new_v2(
Raphaël Gomès
rhg: remember the inode of .hg/dirstate...
r51140 on_disk,
data_size,
tree_metadata.data(py),
uuid.to_owned(),
identity,
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: remember the data file uuid dirstate was loaded with...
r51138 /// Returns an empty DirstateMap. Only used for a new dirstate.
@staticmethod
def new_empty() -> PyResult<PyObject> {
let map = OwningDirstateMap::new_empty(vec![]);
let map = Self::create_instance(py, map)?;
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);
Raphaël Gomès
rust: run `cargo clippy`...
r50809 let was_tracked = res.map_err(|_| PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))?;
Raphaël Gomès
dirstatemap: move `set_tracked` out of common methods and plug in Rust...
r49989 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);
Raphaël Gomès
rust: run `cargo clippy`...
r50809 let was_tracked = res.map_err(|_| PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))?;
Raphaël Gomès
rust-dirstatemap: add `set_untracked` method...
r49999 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,
);
Raphaël Gomès
rust: run `cargo clippy`...
r50809 res.map_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);
Raphaël Gomès
rust: run `cargo clippy`...
r50809 res.map_err(|_| PyErr::new::<exc::OSError, _>(py, "Dirstate error".to_string()))?;
Raphaël Gomès
rust-dirstatemap: add `set_possibly_dirty` method...
r49997 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,
);
Raphaël Gomès
rust: run `cargo clippy`...
r50809 res.map_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))
}