comparison rust/hg-cpython/src/revlog.rs @ 50974:1928b770e3e7

rust: use the new `UncheckedRevision` everywhere applicable This step converts all revisions that shouldn't be considered "valid" in any context to `UncheckedRevison`, allowing `Revision` to be changed for a stronger type in a later changeset. Note that the conversion from unchecked to checked is manual and requires at least some thought from the programmer, although directly using `Revision` is still possible. A later changeset will make this mistake harder to make.
author Rapha?l Gom?s <rgomes@octobus.net>
date Thu, 10 Aug 2023 11:00:34 +0200
parents 58074252db3c
children 4c5f6e95df84
comparison
equal deleted inserted replaced
50973:9929c8a73488 50974:1928b770e3e7
16 PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject, 16 PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
17 }; 17 };
18 use hg::{ 18 use hg::{
19 nodemap::{Block, NodeMapError, NodeTree}, 19 nodemap::{Block, NodeMapError, NodeTree},
20 revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex}, 20 revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex},
21 Revision, 21 Revision, UncheckedRevision,
22 }; 22 };
23 use std::cell::RefCell; 23 use std::cell::RefCell;
24 24
25 /// Return a Struct implementing the Graph trait 25 /// Return a Struct implementing the Graph trait
26 pub(crate) fn pyindex_to_graph( 26 pub(crate) fn pyindex_to_graph(
250 // `index_getitem` does not handle conversion from PyLong, 250 // `index_getitem` does not handle conversion from PyLong,
251 // which expressions such as [e for e in index] internally use. 251 // which expressions such as [e for e in index] internally use.
252 // Note that we don't seem to have a direct way to call 252 // Note that we don't seem to have a direct way to call
253 // PySequence_GetItem (does the job), which would possibly be better 253 // PySequence_GetItem (does the job), which would possibly be better
254 // for performance 254 // for performance
255 let key = match key.extract::<Revision>(py) { 255 let key = match key.extract::<i32>(py) {
256 Ok(rev) => rev.to_py_object(py).into_object(), 256 Ok(rev) => rev.to_py_object(py).into_object(),
257 Err(_) => key, 257 Err(_) => key,
258 }; 258 };
259 self.cindex(py).borrow().inner().get_item(py, key) 259 self.cindex(py).borrow().inner().get_item(py, key)
260 } 260 }
266 def __contains__(&self, item: PyObject) -> PyResult<bool> { 266 def __contains__(&self, item: PyObject) -> PyResult<bool> {
267 // ObjectProtocol does not seem to provide contains(), so 267 // ObjectProtocol does not seem to provide contains(), so
268 // this is an equivalent implementation of the index_contains() 268 // this is an equivalent implementation of the index_contains()
269 // defined in revlog.c 269 // defined in revlog.c
270 let cindex = self.cindex(py).borrow(); 270 let cindex = self.cindex(py).borrow();
271 match item.extract::<Revision>(py) { 271 match item.extract::<i32>(py) {
272 Ok(rev) => { 272 Ok(rev) => {
273 Ok(rev >= -1 && rev < cindex.inner().len(py)? as Revision) 273 Ok(rev >= -1 && rev < cindex.inner().len(py)? as Revision)
274 } 274 }
275 Err(_) => { 275 Err(_) => {
276 cindex.inner().call_method( 276 cindex.inner().call_method(
446 self.mmap(py).borrow_mut().replace(buf); 446 self.mmap(py).borrow_mut().replace(buf);
447 447
448 let mut nt = NodeTree::load_bytes(Box::new(bytes), len); 448 let mut nt = NodeTree::load_bytes(Box::new(bytes), len);
449 449
450 let data_tip = 450 let data_tip =
451 docket.getattr(py, "tip_rev")?.extract::<Revision>(py)?; 451 docket.getattr(py, "tip_rev")?.extract::<i32>(py)?.into();
452 self.docket(py).borrow_mut().replace(docket.clone_ref(py)); 452 self.docket(py).borrow_mut().replace(docket.clone_ref(py));
453 let idx = self.cindex(py).borrow(); 453 let idx = self.cindex(py).borrow();
454 let data_tip = idx.check_revision(data_tip).ok_or_else(|| {
455 nodemap_error(py, NodeMapError::RevisionNotInIndex(data_tip))
456 })?;
454 let current_tip = idx.len(); 457 let current_tip = idx.len();
455 458
456 for r in (data_tip + 1)..current_tip as Revision { 459 for r in (data_tip + 1)..current_tip as Revision {
457 let rev = r as Revision; 460 let rev = r as Revision;
458 // in this case node() won't ever return None 461 // in this case node() won't ever return None
477 cls.call(py, (py.None(),), None).ok().into_py_object(py), 480 cls.call(py, (py.None(),), None).ok().into_py_object(py),
478 ), 481 ),
479 } 482 }
480 } 483 }
481 484
482 fn rev_not_in_index(py: Python, rev: Revision) -> PyErr { 485 fn rev_not_in_index(py: Python, rev: UncheckedRevision) -> PyErr {
483 PyErr::new::<ValueError, _>( 486 PyErr::new::<ValueError, _>(
484 py, 487 py,
485 format!( 488 format!(
486 "Inconsistency: Revision {} found in nodemap \ 489 "Inconsistency: Revision {} found in nodemap \
487 is not in revlog index", 490 is not in revlog index",