##// END OF EJS Templates
rust-cpython: move $leaked struct out of macro...
rust-cpython: move $leaked struct out of macro It wasn't easy to hack the $leaked struct since errors in macro would generate lots of compile errors. Let's make it a plain struct so we can easily extend it. PyLeakedRef keeps a more generic PyObject instead of the $name struct since it no longer has to call any specific methods implemented by the $name class. $leaked parameter in py_shared_iterator!() is kept for future change.

File last commit:

r43447:5cb8867c default
r43447:5cb8867c default
Show More
dirstate_map.rs
528 lines | 16.1 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.
use std::cell::RefCell;
use std::convert::TryInto;
use std::time::Duration;
use cpython::{
exc, ObjectProtocol, PyBool, PyBytes, PyClone, PyDict, PyErr, PyObject,
PyResult, PyTuple, Python, PythonObject, ToPyObject,
};
use libc::c_char;
use crate::{
dirstate::copymap::{CopyMap, CopyMapItemsIterator, CopyMapKeysIterator},
dirstate::{decapsule_make_dirstate_tuple, dirs_multiset::Dirs},
Yuya Nishihara
rust-cpython: move $leaked struct out of macro...
r43447 ref_sharing::{PyLeakedRef, PySharedRefCell},
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 };
use hg::{
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 utils::hg_path::{HgPath, HgPathBuf},
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 DirsMultiset, DirstateEntry, DirstateMap as RustDirstateMap,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 DirstateParents, DirstateParseError, EntryState, StateMapIter,
PARENT_SIZE,
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| {
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 data inner: PySharedRefCell<RustDirstateMap>;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999
def __new__(_cls, _root: PyObject) -> PyResult<Self> {
let inner = RustDirstateMap::default();
Self::create_instance(
py,
Yuya Nishihara
rust-cpython: introduce restricted variant of RefCell...
r43115 PySharedRefCell::new(inner),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def clear(&self) -> PyResult<PyObject> {
self.borrow_mut(py)?.clear();
Ok(py.None())
}
def get(
&self,
key: PyObject,
default: Option<PyObject> = None
) -> 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.inner(py).borrow().get(HgPath::new(key.data(py))) {
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Some(entry) => {
// Explicitly go through u8 first, then cast to
// platform-specific `c_char`.
let state: u8 = entry.state.into();
Ok(Some(decapsule_make_dirstate_tuple(py)?(
state as c_char,
entry.mode,
entry.size,
entry.mtime,
)))
},
None => Ok(default)
}
}
def addfile(
&self,
f: PyObject,
oldstate: PyObject,
state: PyObject,
mode: PyObject,
size: PyObject,
mtime: PyObject
) -> PyResult<PyObject> {
self.borrow_mut(py)?.add_file(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 oldstate.extract::<PyBytes>(py)?.data(py)[0]
.try_into()
.map_err(|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?,
DirstateEntry {
state: state.extract::<PyBytes>(py)?.data(py)[0]
.try_into()
.map_err(|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?,
mode: mode.extract(py)?,
size: size.extract(py)?,
mtime: mtime.extract(py)?,
},
);
Ok(py.None())
}
def removefile(
&self,
f: PyObject,
oldstate: PyObject,
size: PyObject
) -> PyResult<PyObject> {
self.borrow_mut(py)?
.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)),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 oldstate.extract::<PyBytes>(py)?.data(py)[0]
.try_into()
.map_err(|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?,
size.extract(py)?,
)
.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
))
})?;
Ok(py.None())
}
def dropfile(
&self,
f: PyObject,
oldstate: PyObject
) -> PyResult<PyBool> {
self.borrow_mut(py)?
.drop_file(
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 HgPath::new(f.extract::<PyBytes>(py)?.data(py)),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 oldstate.extract::<PyBytes>(py)?.data(py)[0]
.try_into()
.map_err(|e: DirstateParseError| {
PyErr::new::<exc::ValueError, _>(py, e.to_string())
})?,
)
.and_then(|b| Ok(b.to_py_object(py)))
.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
))
})
}
def clearambiguoustimes(
&self,
files: PyObject,
now: PyObject
) -> PyResult<PyObject> {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 let files: PyResult<Vec<HgPathBuf>> = files
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .iter(py)?
.map(|filename| {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 Ok(HgPathBuf::from_bytes(
filename?.extract::<PyBytes>(py)?.data(py),
))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 })
.collect();
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 self.borrow_mut(py)?
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .clear_ambiguous_times(files?, now.extract(py)?);
Ok(py.None())
}
// TODO share the reference
def nonnormalentries(&self) -> PyResult<PyObject> {
let (non_normal, other_parent) =
self.inner(py).borrow().non_normal_other_parent_entries();
let locals = PyDict::new(py);
locals.set_item(
py,
"non_normal",
non_normal
.iter()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .map(|v| PyBytes::new(py, v.as_ref()))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .collect::<Vec<PyBytes>>()
.to_py_object(py),
)?;
locals.set_item(
py,
"other_parent",
other_parent
.iter()
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 .map(|v| PyBytes::new(py, v.as_ref()))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .collect::<Vec<PyBytes>>()
.to_py_object(py),
)?;
py.eval("set(non_normal), set(other_parent)", None, Some(&locals))
}
def hastrackeddir(&self, d: PyObject) -> PyResult<PyBool> {
let d = d.extract::<PyBytes>(py)?;
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 Ok(self.borrow_mut(py)?
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-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: fix unsafe inner(py).borrow_mut() calls...
r43114 Ok(self.borrow_mut(py)?
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-dirstate: rust-cpython bridge for dirstatemap...
r42999 .to_py_object(py))
}
def parents(&self, st: PyObject) -> PyResult<PyTuple> {
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 self.borrow_mut(py)?
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .parents(st.extract::<PyBytes>(py)?.data(py))
.and_then(|d| {
Ok((PyBytes::new(py, &d.p1), PyBytes::new(py, &d.p2))
.to_py_object(py))
})
.or_else(|_| {
Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
))
})
}
def setparents(&self, p1: PyObject, p2: PyObject) -> PyResult<PyObject> {
Yuya Nishihara
rust-dirstate: handle invalid length of p1/p2 parameters...
r43068 let p1 = extract_node_id(py, &p1)?;
let p2 = extract_node_id(py, &p2)?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 self.borrow_mut(py)?
Yuya Nishihara
rust-dirstate: remove excessive clone() of parameter and return value...
r43069 .set_parents(&DirstateParents { p1, p2 });
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Ok(py.None())
}
def read(&self, st: PyObject) -> PyResult<Option<PyObject>> {
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 match self.borrow_mut(py)?
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 .read(st.extract::<PyBytes>(py)?.data(py))
{
Ok(Some(parents)) => Ok(Some(
(PyBytes::new(py, &parents.p1), PyBytes::new(py, &parents.p2))
.to_py_object(py)
.into_object(),
)),
Ok(None) => Ok(Some(py.None())),
Err(_) => Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
)),
}
}
def write(
&self,
p1: PyObject,
p2: PyObject,
now: PyObject
) -> PyResult<PyBytes> {
let now = Duration::new(now.extract(py)?, 0);
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 };
match self.borrow_mut(py)?.pack(parents, now) {
Ok(packed) => Ok(PyBytes::new(py, &packed)),
Err(_) => Err(PyErr::new::<exc::OSError, _>(
py,
"Dirstate error".to_string(),
)),
}
}
def filefoldmapasdict(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 for (key, value) in self.borrow_mut(py)?.build_file_fold_map().iter() {
dict.set_item(py, key.as_ref().to_vec(), value.as_ref().to_vec())?;
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
Ok(dict)
}
def __len__(&self) -> PyResult<usize> {
Ok(self.inner(py).borrow().len())
}
def __contains__(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 Ok(self.inner(py).borrow().contains_key(HgPath::new(key.data(py))))
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));
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 match self.inner(py).borrow().get(key) {
Some(entry) => {
// Explicitly go through u8 first, then cast to
// platform-specific `c_char`.
let state: u8 = entry.state.into();
Ok(decapsule_make_dirstate_tuple(py)?(
state as c_char,
entry.mode,
entry.size,
entry.mtime,
))
},
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: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapKeysIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: remove Option<_> from interface of py_shared_iterator...
r43160 leak_handle,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 leaked_ref.iter(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def items(&self) -> PyResult<DirstateMapItemsIterator> {
Yuya Nishihara
rust-cpython: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapItemsIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: remove Option<_> from interface of py_shared_iterator...
r43160 leak_handle,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 leaked_ref.iter(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
Yuya Nishihara
rust-cpython: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 DirstateMapKeysIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: remove Option<_> from interface of py_shared_iterator...
r43160 leak_handle,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 leaked_ref.iter(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def getdirs(&self) -> PyResult<Dirs> {
// TODO don't copy, share the reference
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 self.borrow_mut(py)?.set_dirs();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Dirs::from_inner(
py,
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 DirsMultiset::from_dirstate(
&self.inner(py).borrow(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Some(EntryState::Removed),
),
)
}
def getalldirs(&self) -> PyResult<Dirs> {
// TODO don't copy, share the reference
Yuya Nishihara
rust-cpython: fix unsafe inner(py).borrow_mut() calls...
r43114 self.borrow_mut(py)?.set_all_dirs();
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Dirs::from_inner(
py,
Yuya Nishihara
rust-dirstate: split DirsMultiset constructor per input type...
r43070 DirsMultiset::from_dirstate(
&self.inner(py).borrow(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 None,
),
)
}
// TODO all copymap* methods, see docstring above
def copymapcopy(&self) -> PyResult<PyDict> {
let dict = PyDict::new(py);
for (key, value) in self.inner(py).borrow().copy_map.iter() {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 dict.set_item(
py,
PyBytes::new(py, key.as_ref()),
PyBytes::new(py, value.as_ref()),
)?;
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)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 match self.inner(py).borrow().copy_map.get(HgPath::new(key.data(py))) {
Some(copy) => Ok(PyBytes::new(py, copy.as_ref())),
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> {
Ok(self.inner(py).borrow().copy_map.len())
}
def copymapcontains(&self, key: PyObject) -> PyResult<bool> {
let key = key.extract::<PyBytes>(py)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 Ok(self
.inner(py)
.borrow()
.copy_map
.contains_key(HgPath::new(key.data(py))))
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
.inner(py)
.borrow()
.copy_map
.get(HgPath::new(key.data(py)))
{
Some(copy) => Ok(Some(
PyBytes::new(py, copy.as_ref()).into_object(),
)),
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)?;
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 self.borrow_mut(py)?.copy_map.insert(
HgPathBuf::from_bytes(key.data(py)),
HgPathBuf::from_bytes(value.data(py)),
);
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
.borrow_mut(py)?
.copy_map
.remove(HgPath::new(key.data(py)))
{
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 Some(_) => Ok(None),
None => Ok(default),
}
}
def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
Yuya Nishihara
rust-cpython: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 CopyMapKeysIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: remove Option<_> from interface of py_shared_iterator...
r43160 leak_handle,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 leaked_ref.copy_map.iter(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
Yuya Nishihara
rust-cpython: mark unsafe functions as such...
r43117 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 CopyMapItemsIterator::from_inner(
py,
Yuya Nishihara
rust-cpython: remove Option<_> from interface of py_shared_iterator...
r43160 leak_handle,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 leaked_ref.copy_map.iter(),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 )
}
});
impl DirstateMap {
fn translate_key(
py: Python,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 res: (&HgPathBuf, &DirstateEntry),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 ) -> PyResult<Option<PyBytes>> {
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 Ok(Some(PyBytes::new(py, res.0.as_ref())))
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 }
fn translate_key_value(
py: Python,
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 res: (&HgPathBuf, &DirstateEntry),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 ) -> PyResult<Option<(PyBytes, PyObject)>> {
let (f, entry) = res;
// Explicitly go through u8 first, then cast to
// platform-specific `c_char`.
let state: u8 = entry.state.into();
Ok(Some((
Raphaël Gomès
rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf...
r43227 PyBytes::new(py, f.as_ref()),
Raphaël Gomès
rust-dirstate: rust-cpython bridge for dirstatemap...
r42999 decapsule_make_dirstate_tuple(py)?(
state as c_char,
entry.mode,
entry.size,
entry.mtime,
),
)))
}
}
Yuya Nishihara
rust-cpython: move $leaked struct out of macro...
r43447 py_shared_ref!(DirstateMap, RustDirstateMap, inner);
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: move $leaked struct out of macro...
r43447 PyLeakedRef,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 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: move $leaked struct out of macro...
r43447 PyLeakedRef,
Yuya Nishihara
rust-cpython: replace dyn Iterator<..> of mapping with concrete type...
r43158 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
fn extract_node_id(py: Python, obj: &PyObject) -> PyResult<[u8; PARENT_SIZE]> {
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())),
}
}