item.rs
285 lines
| 7.8 KiB
| application/rls-services+xml
|
RustLexer
Simon Sapin
|
r48857 | use cpython::exc; | ||
r49068 | use cpython::ObjectProtocol; | |||
Simon Sapin
|
r48857 | use cpython::PyBytes; | ||
use cpython::PyErr; | ||||
use cpython::PyNone; | ||||
use cpython::PyObject; | ||||
use cpython::PyResult; | ||||
use cpython::Python; | ||||
use cpython::PythonObject; | ||||
use hg::dirstate::DirstateEntry; | ||||
use hg::dirstate::EntryState; | ||||
Simon Sapin
|
r49079 | use hg::dirstate::TruncatedTimestamp; | ||
Simon Sapin
|
r48857 | use std::cell::Cell; | ||
use std::convert::TryFrom; | ||||
py_class!(pub class DirstateItem |py| { | ||||
data entry: Cell<DirstateEntry>; | ||||
def __new__( | ||||
_cls, | ||||
wc_tracked: bool = false, | ||||
p1_tracked: bool = false, | ||||
r48950 | p2_info: bool = false, | |||
has_meaningful_data: bool = true, | ||||
has_meaningful_mtime: bool = true, | ||||
r49227 | parentfiledata: Option<(u32, u32, Option<(u32, u32, bool)>)> = None, | |||
r49069 | fallback_exec: Option<bool> = None, | |||
fallback_symlink: Option<bool> = None, | ||||
Simon Sapin
|
r48857 | |||
) -> PyResult<DirstateItem> { | ||||
r48950 | let mut mode_size_opt = None; | |||
let mut mtime_opt = None; | ||||
if let Some((mode, size, mtime)) = parentfiledata { | ||||
if has_meaningful_data { | ||||
mode_size_opt = Some((mode, size)) | ||||
} | ||||
if has_meaningful_mtime { | ||||
r49201 | if let Some(m) = mtime { | |||
mtime_opt = Some(timestamp(py, m)?); | ||||
} | ||||
r48950 | } | |||
} | ||||
Simon Sapin
|
r48951 | let entry = DirstateEntry::from_v2_data( | ||
r49069 | wc_tracked, | |||
p1_tracked, | ||||
p2_info, | ||||
mode_size_opt, | ||||
mtime_opt, | ||||
fallback_exec, | ||||
fallback_symlink, | ||||
r48950 | ); | |||
Simon Sapin
|
r48857 | DirstateItem::create_instance(py, Cell::new(entry)) | ||
} | ||||
@property | ||||
def state(&self) -> PyResult<PyBytes> { | ||||
let state_byte: u8 = self.entry(py).get().state().into(); | ||||
Ok(PyBytes::new(py, &[state_byte])) | ||||
} | ||||
@property | ||||
def mode(&self) -> PyResult<i32> { | ||||
Ok(self.entry(py).get().mode()) | ||||
} | ||||
@property | ||||
def size(&self) -> PyResult<i32> { | ||||
Ok(self.entry(py).get().size()) | ||||
} | ||||
@property | ||||
def mtime(&self) -> PyResult<i32> { | ||||
Ok(self.entry(py).get().mtime()) | ||||
} | ||||
@property | ||||
r49068 | def has_fallback_exec(&self) -> PyResult<bool> { | |||
match self.entry(py).get().get_fallback_exec() { | ||||
Some(_) => Ok(true), | ||||
None => Ok(false), | ||||
} | ||||
} | ||||
@property | ||||
def fallback_exec(&self) -> PyResult<Option<bool>> { | ||||
match self.entry(py).get().get_fallback_exec() { | ||||
Some(exec) => Ok(Some(exec)), | ||||
None => Ok(None), | ||||
} | ||||
} | ||||
@fallback_exec.setter | ||||
def set_fallback_exec(&self, value: Option<PyObject>) -> PyResult<()> { | ||||
match value { | ||||
None => {self.entry(py).get().set_fallback_exec(None);}, | ||||
Some(value) => { | ||||
if value.is_none(py) { | ||||
self.entry(py).get().set_fallback_exec(None); | ||||
} else { | ||||
self.entry(py).get().set_fallback_exec( | ||||
Some(value.is_true(py)?) | ||||
); | ||||
}}, | ||||
} | ||||
Ok(()) | ||||
} | ||||
@property | ||||
def has_fallback_symlink(&self) -> PyResult<bool> { | ||||
match self.entry(py).get().get_fallback_symlink() { | ||||
Some(_) => Ok(true), | ||||
None => Ok(false), | ||||
} | ||||
} | ||||
@property | ||||
def fallback_symlink(&self) -> PyResult<Option<bool>> { | ||||
match self.entry(py).get().get_fallback_symlink() { | ||||
Some(symlink) => Ok(Some(symlink)), | ||||
None => Ok(None), | ||||
} | ||||
} | ||||
@fallback_symlink.setter | ||||
def set_fallback_symlink(&self, value: Option<PyObject>) -> PyResult<()> { | ||||
match value { | ||||
None => {self.entry(py).get().set_fallback_symlink(None);}, | ||||
Some(value) => { | ||||
if value.is_none(py) { | ||||
self.entry(py).get().set_fallback_symlink(None); | ||||
} else { | ||||
self.entry(py).get().set_fallback_symlink( | ||||
Some(value.is_true(py)?) | ||||
); | ||||
}}, | ||||
} | ||||
Ok(()) | ||||
} | ||||
@property | ||||
Simon Sapin
|
r48857 | def tracked(&self) -> PyResult<bool> { | ||
Ok(self.entry(py).get().tracked()) | ||||
} | ||||
@property | ||||
r48955 | def p1_tracked(&self) -> PyResult<bool> { | |||
Ok(self.entry(py).get().p1_tracked()) | ||||
} | ||||
@property | ||||
Simon Sapin
|
r48857 | def added(&self) -> PyResult<bool> { | ||
Ok(self.entry(py).get().added()) | ||||
} | ||||
r48954 | ||||
@property | ||||
def p2_info(&self) -> PyResult<bool> { | ||||
Ok(self.entry(py).get().p2_info()) | ||||
} | ||||
Simon Sapin
|
r48857 | @property | ||
def removed(&self) -> PyResult<bool> { | ||||
Ok(self.entry(py).get().removed()) | ||||
} | ||||
@property | ||||
r48898 | def maybe_clean(&self) -> PyResult<bool> { | |||
Ok(self.entry(py).get().maybe_clean()) | ||||
} | ||||
r48899 | @property | |||
def any_tracked(&self) -> PyResult<bool> { | ||||
Ok(self.entry(py).get().any_tracked()) | ||||
} | ||||
Simon Sapin
|
r48857 | def v1_state(&self) -> PyResult<PyBytes> { | ||
let (state, _mode, _size, _mtime) = self.entry(py).get().v1_data(); | ||||
let state_byte: u8 = state.into(); | ||||
Ok(PyBytes::new(py, &[state_byte])) | ||||
} | ||||
def v1_mode(&self) -> PyResult<i32> { | ||||
let (_state, mode, _size, _mtime) = self.entry(py).get().v1_data(); | ||||
Ok(mode) | ||||
} | ||||
def v1_size(&self) -> PyResult<i32> { | ||||
let (_state, _mode, size, _mtime) = self.entry(py).get().v1_data(); | ||||
Ok(size) | ||||
} | ||||
def v1_mtime(&self) -> PyResult<i32> { | ||||
let (_state, _mode, _size, mtime) = self.entry(py).get().v1_data(); | ||||
Ok(mtime) | ||||
} | ||||
r49227 | def mtime_likely_equal_to(&self, other: (u32, u32, bool)) | |||
-> PyResult<bool> { | ||||
Simon Sapin
|
r49079 | if let Some(mtime) = self.entry(py).get().truncated_mtime() { | ||
Ok(mtime.likely_equal(timestamp(py, other)?)) | ||||
} else { | ||||
Ok(false) | ||||
} | ||||
} | ||||
Simon Sapin
|
r48857 | @classmethod | ||
def from_v1_data( | ||||
_cls, | ||||
state: PyBytes, | ||||
mode: i32, | ||||
size: i32, | ||||
mtime: i32, | ||||
) -> PyResult<Self> { | ||||
let state = <[u8; 1]>::try_from(state.data(py)) | ||||
.ok() | ||||
.and_then(|state| EntryState::try_from(state[0]).ok()) | ||||
.ok_or_else(|| PyErr::new::<exc::ValueError, _>(py, "invalid state"))?; | ||||
let entry = DirstateEntry::from_v1_data(state, mode, size, mtime); | ||||
DirstateItem::create_instance(py, Cell::new(entry)) | ||||
} | ||||
r48946 | def drop_merge_data(&self) -> PyResult<PyNone> { | |||
self.update(py, |entry| entry.drop_merge_data()); | ||||
Ok(PyNone) | ||||
} | ||||
Simon Sapin
|
r48857 | def set_clean( | ||
&self, | ||||
Simon Sapin
|
r49008 | mode: u32, | ||
size: u32, | ||||
r49227 | mtime: (u32, u32, bool), | |||
Simon Sapin
|
r48857 | ) -> PyResult<PyNone> { | ||
Simon Sapin
|
r49079 | let mtime = timestamp(py, mtime)?; | ||
Simon Sapin
|
r48857 | self.update(py, |entry| entry.set_clean(mode, size, mtime)); | ||
Ok(PyNone) | ||||
} | ||||
def set_possibly_dirty(&self) -> PyResult<PyNone> { | ||||
self.update(py, |entry| entry.set_possibly_dirty()); | ||||
Ok(PyNone) | ||||
} | ||||
def set_tracked(&self) -> PyResult<PyNone> { | ||||
self.update(py, |entry| entry.set_tracked()); | ||||
Ok(PyNone) | ||||
} | ||||
def set_untracked(&self) -> PyResult<PyNone> { | ||||
self.update(py, |entry| entry.set_untracked()); | ||||
Ok(PyNone) | ||||
} | ||||
}); | ||||
impl DirstateItem { | ||||
pub fn new_as_pyobject( | ||||
py: Python<'_>, | ||||
entry: DirstateEntry, | ||||
) -> PyResult<PyObject> { | ||||
Ok(DirstateItem::create_instance(py, Cell::new(entry))?.into_object()) | ||||
} | ||||
Simon Sapin
|
r48859 | pub fn get_entry(&self, py: Python<'_>) -> DirstateEntry { | ||
self.entry(py).get() | ||||
} | ||||
Simon Sapin
|
r48857 | // TODO: Use https://doc.rust-lang.org/std/cell/struct.Cell.html#method.update instead when it’s stable | ||
pub fn update(&self, py: Python<'_>, f: impl FnOnce(&mut DirstateEntry)) { | ||||
let mut entry = self.entry(py).get(); | ||||
f(&mut entry); | ||||
self.entry(py).set(entry) | ||||
} | ||||
} | ||||
Simon Sapin
|
r49079 | |||
pub(crate) fn timestamp( | ||||
py: Python<'_>, | ||||
r49227 | (s, ns, second_ambiguous): (u32, u32, bool), | |||
Simon Sapin
|
r49079 | ) -> PyResult<TruncatedTimestamp> { | ||
r49227 | TruncatedTimestamp::from_already_truncated(s, ns, second_ambiguous) | |||
.map_err(|_| { | ||||
PyErr::new::<exc::ValueError, _>( | ||||
py, | ||||
"expected mtime truncated to 31 bits", | ||||
) | ||||
}) | ||||
Simon Sapin
|
r49079 | } | ||