rust/hg-cpython/src/revlog.rs
author Raphaël Gomès <rgomes@octobus.net>
Fri, 18 Aug 2023 14:34:29 +0200
changeset 50979 4c5f6e95df84
parent 50977 1928b770e3e7
child 51120 532e74ad3ff6
permissions -rw-r--r--
rust: make `Revision` a newtype This change is the one we've been building towards during this series. The aim is to make `Revision` mean more than a simple integer, holding the information that it is valid for a given revlog index. While this still allows for programmer error, since creating a revision directly and querying a different index with a "checked" revision are still possible, the friction created by the newtype will hopefully make us think twice about which type to use. Enough of the Rust ecosystem relies on the newtype pattern to be efficiently optimized away (even compiler in codegen testsĀ¹), so I'm not worried about this being a fundamental problem. [1] https://github.com/rust-lang/rust/blob/7a70647f195f6b0a0f1ebd72b1542ba91a32f43a/tests/codegen/vec-in-place.rs#L47
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     1
// revlog.rs
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     2
//
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
     3
// Copyright 2019-2020 Georges Racinet <georges.racinet@octobus.net>
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     4
//
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
     7
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
     8
use crate::{
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
     9
    cindex,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    10
    utils::{node_from_py_bytes, node_from_py_object},
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    11
    PyRevision,
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    12
};
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    13
use cpython::{
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
    14
    buffer::{Element, PyBuffer},
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    15
    exc::{IndexError, ValueError},
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
    16
    ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyInt, PyModule,
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
    17
    PyObject, PyResult, PyString, PyTuple, Python, PythonObject, ToPyObject,
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    18
};
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    19
use hg::{
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
    20
    nodemap::{Block, NodeMapError, NodeTree},
46432
18a261b11b20 rust: Remove hex parsing from the nodemap
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
    21
    revlog::{nodemap::NodeMap, NodePrefix, RevlogIndex},
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    22
    BaseRevision, Revision, UncheckedRevision,
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    23
};
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    24
use std::cell::RefCell;
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    25
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    26
/// Return a Struct implementing the Graph trait
44070
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    27
pub(crate) fn pyindex_to_graph(
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    28
    py: Python,
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    29
    index: PyObject,
451d22174b5f revlog: run rustfmt nightly
Augie Fackler <augie@google.com>
parents: 44012
diff changeset
    30
) -> PyResult<cindex::Index> {
44011
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    31
    match index.extract::<MixedIndex>(py) {
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    32
        Ok(midx) => Ok(midx.clone_cindex(py)),
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    33
        Err(_) => cindex::Index::new(py, index),
c627f1b2f3c3 rust-index: handle `MixedIndex` in `pyindex_to_graph`
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44010
diff changeset
    34
    }
43945
f98f0e3ddaa1 rust-index: add a function to convert PyObject index for hg-core
Pierre-Yves David <pierre-yves.david@octobus.net>
parents:
diff changeset
    35
}
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    36
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    37
py_class!(pub class MixedIndex |py| {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    38
    data cindex: RefCell<cindex::Index>;
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    39
    data nt: RefCell<Option<NodeTree>>;
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
    40
    data docket: RefCell<Option<PyObject>>;
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
    41
    // Holds a reference to the mmap'ed persistent nodemap data
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
    42
    data mmap: RefCell<Option<PyBuffer>>;
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    43
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    44
    def __new__(_cls, cindex: PyObject) -> PyResult<MixedIndex> {
44503
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
    45
        Self::new(py, cindex)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    46
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    47
44012
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    48
    /// Compatibility layer used for Python consumers needing access to the C index
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    49
    ///
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    50
    /// Only use case so far is `scmutil.shortesthexnodeidprefix`,
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    51
    /// that may need to build a custom `nodetree`, based on a specified revset.
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    52
    /// With a Rust implementation of the nodemap, we will be able to get rid of
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    53
    /// this, by exposing our own standalone nodemap class,
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    54
    /// ready to accept `MixedIndex`.
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    55
    def get_cindex(&self) -> PyResult<PyObject> {
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    56
        Ok(self.cindex(py).borrow().inner().clone_ref(py))
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    57
    }
443dc1655923 rust-index: expose a method to retrieve the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 44011
diff changeset
    58
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    59
    // Index API involving nodemap, as defined in mercurial/pure/parsers.py
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
    60
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    61
    /// Return Revision if found, raises a bare `error.RevlogError`
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    62
    /// in case of ambiguity, same as C version does
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    63
    def get_rev(&self, node: PyBytes) -> PyResult<Option<PyRevision>> {
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    64
        let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    65
        let nt = opt.as_ref().unwrap();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    66
        let idx = &*self.cindex(py).borrow();
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
    67
        let node = node_from_py_bytes(py, &node)?;
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    68
        let res = nt.find_bin(idx, node.into());
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    69
        Ok(res.map_err(|e| nodemap_error(py, e))?.map(Into::into))
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    70
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    71
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    72
    /// same as `get_rev()` but raises a bare `error.RevlogError` if node
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    73
    /// is not found.
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    74
    ///
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    75
    /// No need to repeat `node` in the exception, `mercurial/revlog.py`
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    76
    /// will catch and rewrap with it
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
    77
    def rev(&self, node: PyBytes) -> PyResult<PyRevision> {
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    78
        self.get_rev(py, node)?.ok_or_else(|| revlog_error(py))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    79
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    80
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    81
    /// return True if the node exist in the index
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    82
    def has_node(&self, node: PyBytes) -> PyResult<bool> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    83
        self.get_rev(py, node).map(|opt| opt.is_some())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    84
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    85
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    86
    /// find length of shortest hex nodeid of a binary ID
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    87
    def shortest(&self, node: PyBytes) -> PyResult<usize> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    88
        let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    89
        let nt = opt.as_ref().unwrap();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    90
        let idx = &*self.cindex(py).borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    91
        match nt.unique_prefix_len_node(idx, &node_from_py_bytes(py, &node)?)
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    92
        {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    93
            Ok(Some(l)) => Ok(l),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    94
            Ok(None) => Err(revlog_error(py)),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    95
            Err(e) => Err(nodemap_error(py, e)),
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    96
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    97
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
    98
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
    99
    def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> {
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   100
        let opt = self.get_nodetree(py)?.borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   101
        let nt = opt.as_ref().unwrap();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   102
        let idx = &*self.cindex(py).borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   103
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   104
        let node_as_string = if cfg!(feature = "python3-sys") {
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   105
            node.cast_as::<PyString>(py)?.to_string(py)?.to_string()
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   106
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   107
        else {
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   108
            let node = node.extract::<PyBytes>(py)?;
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   109
            String::from_utf8_lossy(node.data(py)).to_string()
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   110
        };
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   111
49374
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   112
        let prefix = NodePrefix::from_hex(&node_as_string)
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   113
            .map_err(|_| PyErr::new::<ValueError, _>(
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   114
                py, format!("Invalid node or prefix '{}'", node_as_string))
455fce57e89e rust: don't swallow valuable error information
Raphaël Gomès <rgomes@octobus.net>
parents: 48269
diff changeset
   115
            )?;
46432
18a261b11b20 rust: Remove hex parsing from the nodemap
Simon Sapin <simon.sapin@octobus.net>
parents: 46431
diff changeset
   116
48269
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   117
        nt.find_bin(idx, prefix)
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   118
            // TODO make an inner API returning the node directly
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   119
            .map(|opt| opt.map(
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   120
                |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes())))
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   121
            .map_err(|e| nodemap_error(py, e))
aa88fb60ecb4 rust-nodemap: backed out mitigation for issue 6554
Georges Racinet <georges.racinet@octobus.net>
parents: 47799
diff changeset
   122
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   123
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   124
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   125
    /// append an index entry
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   126
    def append(&self, tup: PyTuple) -> PyResult<PyObject> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   127
        if tup.len(py) < 8 {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   128
            // this is better than the panic promised by tup.get_item()
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   129
            return Err(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   130
                PyErr::new::<IndexError, _>(py, "tuple index out of range"))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   131
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   132
        let node_bytes = tup.get_item(py, 7).extract(py)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   133
        let node = node_from_py_object(py, &node_bytes)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   134
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   135
        let mut idx = self.cindex(py).borrow_mut();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   136
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   137
        // This is ok since we will just add the revision to the index
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   138
        let rev = Revision(idx.len() as BaseRevision);
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   139
        idx.append(py, tup)?;
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   140
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   141
        self.get_nodetree(py)?.borrow_mut().as_mut().unwrap()
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   142
            .insert(&*idx, &node, rev)
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   143
            .map_err(|e| nodemap_error(py, e))?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   144
        Ok(py.None())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   145
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   146
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   147
    def __delitem__(&self, key: PyObject) -> PyResult<()> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   148
        // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]`
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   149
        self.cindex(py).borrow().inner().del_item(py, key)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   150
        let mut opt = self.get_nodetree(py)?.borrow_mut();
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49374
diff changeset
   151
        let nt = opt.as_mut().unwrap();
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   152
        nt.invalidate_all();
49914
58074252db3c rust: run `cargo clippy`
Raphaël Gomès <rgomes@octobus.net>
parents: 49374
diff changeset
   153
        self.fill_nodemap(py, nt)?;
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   154
        Ok(())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   155
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   156
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   157
    //
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   158
    // Reforwarded C index API
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   159
    //
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   160
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   161
    // index_methods (tp_methods). Same ordering as in revlog.c
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   162
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   163
    /// return the gca set of the given revs
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   164
    def ancestors(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   165
        self.call_cindex(py, "ancestors", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   166
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   167
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   168
    /// return the heads of the common ancestors of the given revs
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   169
    def commonancestorsheads(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   170
        self.call_cindex(py, "commonancestorsheads", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   171
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   172
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   173
    /// Clear the index caches and inner py_class data.
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   174
    /// It is Python's responsibility to call `update_nodemap_data` again.
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   175
    def clearcaches(&self, *args, **kw) -> PyResult<PyObject> {
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   176
        self.nt(py).borrow_mut().take();
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   177
        self.docket(py).borrow_mut().take();
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   178
        self.mmap(py).borrow_mut().take();
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   179
        self.call_cindex(py, "clearcaches", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   180
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   181
47034
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   182
    /// return the raw binary string representing a revision
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   183
    def entry_binary(&self, *args, **kw) -> PyResult<PyObject> {
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   184
        self.call_cindex(py, "entry_binary", args, kw)
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   185
    }
0d8ff1f4ab0c revlog: add a `entry_binary` method on index
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46974
diff changeset
   186
47037
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   187
    /// return a binary packed version of the header
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   188
    def pack_header(&self, *args, **kw) -> PyResult<PyObject> {
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   189
        self.call_cindex(py, "pack_header", args, kw)
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   190
    }
d57386e5c80e revlog: have an explicit "pack_header" method
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47034
diff changeset
   191
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   192
    /// get an index entry
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   193
    def get(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   194
        self.call_cindex(py, "get", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   195
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   196
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   197
    /// compute phases
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   198
    def computephasesmapsets(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   199
        self.call_cindex(py, "computephasesmapsets", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   200
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   201
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   202
    /// reachableroots
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   203
    def reachableroots2(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   204
        self.call_cindex(py, "reachableroots2", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   205
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   206
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   207
    /// get head revisions
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   208
    def headrevs(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   209
        self.call_cindex(py, "headrevs", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   210
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   211
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   212
    /// get filtered head revisions
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   213
    def headrevsfiltered(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   214
        self.call_cindex(py, "headrevsfiltered", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   215
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   216
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   217
    /// True if the object is a snapshot
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   218
    def issnapshot(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   219
        self.call_cindex(py, "issnapshot", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   220
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   221
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   222
    /// Gather snapshot data in a cache dict
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   223
    def findsnapshots(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   224
        self.call_cindex(py, "findsnapshots", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   225
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   226
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   227
    /// determine revisions with deltas to reconstruct fulltext
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   228
    def deltachain(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   229
        self.call_cindex(py, "deltachain", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   230
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   231
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   232
    /// slice planned chunk read to reach a density threshold
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   233
    def slicechunktodensity(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   234
        self.call_cindex(py, "slicechunktodensity", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   235
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   236
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   237
    /// stats for the index
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   238
    def stats(&self, *args, **kw) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   239
        self.call_cindex(py, "stats", args, kw)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   240
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   241
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   242
    // index_sequence_methods and index_mapping_methods.
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   243
    //
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   244
    // Since we call back through the high level Python API,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   245
    // there's no point making a distinction between index_get
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   246
    // and index_getitem.
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   247
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   248
    def __len__(&self) -> PyResult<usize> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   249
        self.cindex(py).borrow().inner().len(py)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   250
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   251
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   252
    def __getitem__(&self, key: PyObject) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   253
        // this conversion seems needless, but that's actually because
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   254
        // `index_getitem` does not handle conversion from PyLong,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   255
        // which expressions such as [e for e in index] internally use.
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   256
        // Note that we don't seem to have a direct way to call
44511
cadcc8c20860 rust-nodemap: also clear Rust data in `clearcaches`
Georges Racinet <georges.racinet@octobus.net>
parents: 44510
diff changeset
   257
        // PySequence_GetItem (does the job), which would possibly be better
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   258
        // for performance
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   259
        let key = match key.extract::<i32>(py) {
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   260
            Ok(rev) => rev.to_py_object(py).into_object(),
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   261
            Err(_) => key,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   262
        };
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   263
        self.cindex(py).borrow().inner().get_item(py, key)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   264
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   265
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   266
    def __setitem__(&self, key: PyObject, value: PyObject) -> PyResult<()> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   267
        self.cindex(py).borrow().inner().set_item(py, key, value)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   268
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   269
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   270
    def __contains__(&self, item: PyObject) -> PyResult<bool> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   271
        // ObjectProtocol does not seem to provide contains(), so
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   272
        // this is an equivalent implementation of the index_contains()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   273
        // defined in revlog.c
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   274
        let cindex = self.cindex(py).borrow();
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   275
        match item.extract::<i32>(py) {
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   276
            Ok(rev) => {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   277
                Ok(rev >= -1 && rev < cindex.inner().len(py)? as BaseRevision)
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   278
            }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   279
            Err(_) => {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   280
                cindex.inner().call_method(
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   281
                    py,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   282
                    "has_node",
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   283
                    PyTuple::new(py, &[item]),
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   284
                    None)?
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   285
                .extract(py)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   286
            }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   287
        }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   288
    }
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   289
44508
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   290
    def nodemap_data_all(&self) -> PyResult<PyBytes> {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   291
        self.inner_nodemap_data_all(py)
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   292
    }
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   293
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   294
    def nodemap_data_incremental(&self) -> PyResult<PyObject> {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   295
        self.inner_nodemap_data_incremental(py)
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   296
    }
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   297
    def update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   298
        &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   299
        docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   300
        nm_data: PyObject
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   301
    ) -> PyResult<PyObject> {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   302
        self.inner_update_nodemap_data(py, docket, nm_data)
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   303
    }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   304
46974
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
   305
    @property
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
   306
    def entry_size(&self) -> PyResult<PyInt> {
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
   307
        self.cindex(py).borrow().inner().getattr(py, "entry_size")?.extract::<PyInt>(py)
3c9208702db3 revlog: replace revlog._io.size with a new revlog.index.entry_size
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46432
diff changeset
   308
    }
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   309
47268
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   310
    @property
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   311
    def rust_ext_compat(&self) -> PyResult<PyInt> {
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   312
        self.cindex(py).borrow().inner().getattr(py, "rust_ext_compat")?.extract::<PyInt>(py)
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   313
    }
9d1a8829f959 revlog: signal which revlog index are compatible with Rust
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 47037
diff changeset
   314
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   315
});
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   316
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   317
impl MixedIndex {
44503
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   318
    fn new(py: Python, cindex: PyObject) -> PyResult<MixedIndex> {
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   319
        Self::create_instance(
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   320
            py,
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   321
            RefCell::new(cindex::Index::new(py, cindex)?),
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   322
            RefCell::new(None),
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   323
            RefCell::new(None),
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   324
            RefCell::new(None),
44503
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   325
        )
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   326
    }
887d0f921b34 rust-index: moved constructor in separate impl block
Georges Racinet <georges.racinet@octobus.net>
parents: 44070
diff changeset
   327
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   328
    /// This is scaffolding at this point, but it could also become
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   329
    /// a way to start a persistent nodemap or perform a
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   330
    /// vacuum / repack operation
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   331
    fn fill_nodemap(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   332
        &self,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   333
        py: Python,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   334
        nt: &mut NodeTree,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   335
    ) -> PyResult<PyObject> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   336
        let index = self.cindex(py).borrow();
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   337
        for r in 0..index.len() {
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   338
            let rev = Revision(r as BaseRevision);
44507
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   339
            // in this case node() won't ever return None
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   340
            nt.insert(&*index, index.node(rev).unwrap(), rev)
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   341
                .map_err(|e| nodemap_error(py, e))?
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   342
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   343
        Ok(py.None())
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   344
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   345
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   346
    fn get_nodetree<'a>(
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   347
        &'a self,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   348
        py: Python<'a>,
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   349
    ) -> PyResult<&'a RefCell<Option<NodeTree>>> {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   350
        if self.nt(py).borrow().is_none() {
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   351
            let readonly = Box::new(Vec::new());
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   352
            let mut nt = NodeTree::load_bytes(readonly, 0);
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   353
            self.fill_nodemap(py, &mut nt)?;
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   354
            self.nt(py).borrow_mut().replace(nt);
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   355
        }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   356
        Ok(self.nt(py))
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   357
    }
857cc79247ac rust-nodemap: use proper Index API instead of using the C API
Raphaël Gomès <rgomes@octobus.net>
parents: 44506
diff changeset
   358
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   359
    /// forward a method call to the underlying C index
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   360
    fn call_cindex(
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   361
        &self,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   362
        py: Python,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   363
        name: &str,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   364
        args: &PyTuple,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   365
        kwargs: Option<&PyDict>,
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   366
    ) -> PyResult<PyObject> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   367
        self.cindex(py)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   368
            .borrow()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   369
            .inner()
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   370
            .call_method(py, name, args, kwargs)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   371
    }
44010
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   372
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   373
    pub fn clone_cindex(&self, py: Python) -> cindex::Index {
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   374
        self.cindex(py).borrow().clone_ref(py)
2728fcb8127c rust-index: make it possible to clone the struct referencing the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43961
diff changeset
   375
    }
44508
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   376
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   377
    /// Returns the full nodemap bytes to be written as-is to disk
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   378
    fn inner_nodemap_data_all(&self, py: Python) -> PyResult<PyBytes> {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   379
        let nodemap = self.get_nodetree(py)?.borrow_mut().take().unwrap();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   380
        let (readonly, bytes) = nodemap.into_readonly_and_added_bytes();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   381
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   382
        // If there's anything readonly, we need to build the data again from
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   383
        // scratch
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   384
        let bytes = if readonly.len() > 0 {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   385
            let mut nt = NodeTree::load_bytes(Box::new(vec![]), 0);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   386
            self.fill_nodemap(py, &mut nt)?;
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   387
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   388
            let (readonly, bytes) = nt.into_readonly_and_added_bytes();
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   389
            assert_eq!(readonly.len(), 0);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   390
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   391
            bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   392
        } else {
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   393
            bytes
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   394
        };
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   395
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   396
        let bytes = PyBytes::new(py, &bytes);
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   397
        Ok(bytes)
b581231ae9d1 rust-nodemap: add binding for `nodemap_data_all`
Georges Racinet <georges.racinet@octobus.net>
parents: 44507
diff changeset
   398
    }
44509
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   399
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   400
    /// Returns the last saved docket along with the size of any changed data
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   401
    /// (in number of blocks), and said data as bytes.
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   402
    fn inner_nodemap_data_incremental(
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   403
        &self,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   404
        py: Python,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   405
    ) -> PyResult<PyObject> {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   406
        let docket = self.docket(py).borrow();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   407
        let docket = match docket.as_ref() {
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   408
            Some(d) => d,
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   409
            None => return Ok(py.None()),
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   410
        };
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   411
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   412
        let node_tree = self.get_nodetree(py)?.borrow_mut().take().unwrap();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   413
        let masked_blocks = node_tree.masked_readonly_blocks();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   414
        let (_, data) = node_tree.into_readonly_and_added_bytes();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   415
        let changed = masked_blocks * std::mem::size_of::<Block>();
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   416
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   417
        Ok((docket, changed, PyBytes::new(py, &data))
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   418
            .to_py_object(py)
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   419
            .into_object())
5bbf887275b0 rust-nodemap: add binding for `nodemap_data_incremental`
Georges Racinet <georges.racinet@octobus.net>
parents: 44508
diff changeset
   420
    }
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   421
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   422
    /// Update the nodemap from the new (mmaped) data.
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   423
    /// The docket is kept as a reference for later incremental calls.
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   424
    fn inner_update_nodemap_data(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   425
        &self,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   426
        py: Python,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   427
        docket: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   428
        nm_data: PyObject,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   429
    ) -> PyResult<PyObject> {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   430
        let buf = PyBuffer::get(py, &nm_data)?;
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   431
        let len = buf.item_count();
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   432
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   433
        // Build a slice from the mmap'ed buffer data
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   434
        let cbuf = buf.buf_ptr();
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   435
        let bytes = if std::mem::size_of::<u8>() == buf.item_size()
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   436
            && buf.is_c_contiguous()
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   437
            && u8::is_compatible_format(buf.format())
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   438
        {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   439
            unsafe { std::slice::from_raw_parts(cbuf as *const u8, len) }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   440
        } else {
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   441
            return Err(PyErr::new::<ValueError, _>(
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   442
                py,
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   443
                "Nodemap data buffer has an invalid memory representation"
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   444
                    .to_string(),
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   445
            ));
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   446
        };
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   447
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   448
        // Keep a reference to the mmap'ed buffer, otherwise we get a dangling
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   449
        // pointer.
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   450
        self.mmap(py).borrow_mut().replace(buf);
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   451
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   452
        let mut nt = NodeTree::load_bytes(Box::new(bytes), len);
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   453
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   454
        let data_tip = docket
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   455
            .getattr(py, "tip_rev")?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   456
            .extract::<BaseRevision>(py)?
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   457
            .into();
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   458
        self.docket(py).borrow_mut().replace(docket.clone_ref(py));
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   459
        let idx = self.cindex(py).borrow();
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   460
        let data_tip = idx.check_revision(data_tip).ok_or_else(|| {
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   461
            nodemap_error(py, NodeMapError::RevisionNotInIndex(data_tip))
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   462
        })?;
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   463
        let current_tip = idx.len();
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   464
50979
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   465
        for r in (data_tip.0 + 1)..current_tip as BaseRevision {
4c5f6e95df84 rust: make `Revision` a newtype
Raphaël Gomès <rgomes@octobus.net>
parents: 50977
diff changeset
   466
            let rev = Revision(r);
44510
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   467
            // in this case node() won't ever return None
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   468
            nt.insert(&*idx, idx.node(rev).unwrap(), rev)
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   469
                .map_err(|e| nodemap_error(py, e))?
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   470
        }
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   471
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   472
        *self.nt(py).borrow_mut() = Some(nt);
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   473
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   474
        Ok(py.None())
15febf99a9c6 rust-nodemap: add binding to `nodemap_update_data`
Georges Racinet <georges.racinet@octobus.net>
parents: 44509
diff changeset
   475
    }
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   476
}
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   477
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   478
fn revlog_error(py: Python) -> PyErr {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   479
    match py
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   480
        .import("mercurial.error")
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   481
        .and_then(|m| m.get(py, "RevlogError"))
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   482
    {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   483
        Err(e) => e,
47305
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   484
        Ok(cls) => PyErr::from_instance(
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   485
            py,
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   486
            cls.call(py, (py.None(),), None).ok().into_py_object(py),
33e7508b0ae9 hg-cpython: fix new occuring TypeError
Raphaël Gomès <rgomes@octobus.net>
parents: 47268
diff changeset
   487
        ),
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   488
    }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   489
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   490
50977
1928b770e3e7 rust: use the new `UncheckedRevision` everywhere applicable
Raphaël Gomès <rgomes@octobus.net>
parents: 49914
diff changeset
   491
fn rev_not_in_index(py: Python, rev: UncheckedRevision) -> PyErr {
44506
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   492
    PyErr::new::<ValueError, _>(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   493
        py,
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   494
        format!(
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   495
            "Inconsistency: Revision {} found in nodemap \
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   496
             is not in revlog index",
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   497
            rev
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   498
        ),
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   499
    )
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   500
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   501
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   502
/// Standard treatment of NodeMapError
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   503
fn nodemap_error(py: Python, err: NodeMapError) -> PyErr {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   504
    match err {
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   505
        NodeMapError::MultipleResults => revlog_error(py),
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   506
        NodeMapError::RevisionNotInIndex(r) => rev_not_in_index(py, r),
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   507
    }
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   508
}
26dd35ac59b8 rust-nodemap: add utils for propagating errors
Georges Racinet <georges.racinet@octobus.net>
parents: 44503
diff changeset
   509
43961
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   510
/// Create the module, with __package__ given from parent
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   511
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   512
    let dotted_name = &format!("{}.revlog", package);
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   513
    let m = PyModule::new(py, dotted_name)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   514
    m.add(py, "__package__", package)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   515
    m.add(py, "__doc__", "RevLog - Rust implementations")?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   516
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   517
    m.add_class::<MixedIndex>(py)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   518
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   519
    let sys = PyModule::import(py, "sys")?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   520
    let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   521
    sys_modules.set_item(py, dotted_name, &m)?;
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   522
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   523
    Ok(m)
b69d5f3a41d0 rust-index: add a struct wrapping the C index
Georges Racinet <georges.racinet@octobus.net>
parents: 43945
diff changeset
   524
}