Mercurial > public > mercurial-scm > hg
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", |