rust/hg-cpython/src/dirstate/dirs_multiset.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 02 Jan 2025 14:50:06 +0100
changeset 52592 87ceb51d124c
parent 52410 15011324a80b
permissions -rw-r--r--
run-tests: drop jython support I don't think we heard anything about jython support for the past 15 years, so let's drop special support for it in run-tests.py it is most probably broken at that point.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42746
b3518b0baa47 rust-dirstate: create dirstate submodule in hg-cpython
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
     1
// dirs_multiset.rs
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     2
//
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     4
//
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     7
42746
b3518b0baa47 rust-dirstate: create dirstate submodule in hg-cpython
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
     8
//! Bindings for the `hg::dirstate::dirs_multiset` file provided by the
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     9
//! `hg-core` package.
42746
b3518b0baa47 rust-dirstate: create dirstate submodule in hg-cpython
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42609
diff changeset
    10
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    11
use cpython::{
48021
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    12
    exc, ObjectProtocol, PyBytes, PyClone, PyDict, PyErr, PyObject, PyResult,
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    13
    Python, UnsafePyLeaked,
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    14
};
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    15
42887
706104dcb2c8 rust-cpython: replace dyn Iterator<..> of sequence with concrete type
Yuya Nishihara <yuya@tcha.org>
parents: 42851
diff changeset
    16
use hg::{
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 50534
diff changeset
    17
    dirstate::dirs_multiset::{DirsMultiset, DirsMultisetIter},
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    18
    utils::hg_path::{HgPath, HgPathBuf},
42887
706104dcb2c8 rust-cpython: replace dyn Iterator<..> of sequence with concrete type
Yuya Nishihara <yuya@tcha.org>
parents: 42851
diff changeset
    19
};
42303
e240bec26626 rust-dirstate: add rust-cpython bindings to the new parse/pack functions
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    20
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    21
py_class!(pub class Dirs |py| {
44234
bad4e7b361d2 rust-cpython: switch to upstreamed version of PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents: 44233
diff changeset
    22
    @shared data inner: DirsMultiset;
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    23
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    24
    // `map` is either a `dict` or a flat iterator (usually a `set`, sometimes
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    25
    // a `list`)
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    26
    def __new__(
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    27
        _cls,
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    28
        map: PyObject,
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    29
    ) -> PyResult<Self> {
48021
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    30
        let inner = if map.cast_as::<PyDict>(py).is_ok() {
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    31
            let err = "pathutil.dirs() with a dict should only be used by the Python dirstatemap \
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    32
                and should not be used when Rust is enabled";
627cd8f33db0 rust: Remove support for passing a dict to the Rust pathutil.dirs()
Simon Sapin <simon.sapin@octobus.net>
parents: 47944
diff changeset
    33
            return Err(PyErr::new::<exc::TypeError, _>(py, err.to_string()))
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    34
        } else {
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    35
            let map: Result<Vec<HgPathBuf>, PyErr> = map
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    36
                .iter(py)?
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    37
                .map(|o| {
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    38
                    Ok(HgPathBuf::from_bytes(
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    39
                        o?.extract::<PyBytes>(py)?.data(py),
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    40
                    ))
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    41
                })
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    42
                .collect();
42802
2e1f74cc3350 rust-dirstate: split DirsMultiset constructor per input type
Yuya Nishihara <yuya@tcha.org>
parents: 42752
diff changeset
    43
            DirsMultiset::from_manifest(&map?)
43863
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43788
diff changeset
    44
                .map_err(|e| {
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43788
diff changeset
    45
                    PyErr::new::<exc::ValueError, _>(py, e.to_string())
bc7d8f45c3b6 rust-dirs: handle forgotten `Result`s
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43788
diff changeset
    46
                })?
42748
7cae6bc29ff9 rust-parsers: switch to parse/pack_dirstate to mutate-on-loop
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42746
diff changeset
    47
        };
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    48
44234
bad4e7b361d2 rust-cpython: switch to upstreamed version of PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents: 44233
diff changeset
    49
        Self::create_instance(py, inner)
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    50
    }
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    51
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    52
    def addpath(&self, path: PyObject) -> PyResult<PyObject> {
44233
281642cd1d04 rust-cpython: rename inner_shared() to inner()
Yuya Nishihara <yuya@tcha.org>
parents: 44203
diff changeset
    53
        self.inner(py).borrow_mut().add_path(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    54
            HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
50534
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    55
        ).and(Ok(py.None())).map_err(|e| PyErr::new::<exc::ValueError, _>(
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43430
diff changeset
    56
                        py,
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43430
diff changeset
    57
                        e.to_string(),
50534
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    58
                    )
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    59
        )
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    60
    }
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    61
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    62
    def delpath(&self, path: PyObject) -> PyResult<PyObject> {
44233
281642cd1d04 rust-cpython: rename inner_shared() to inner()
Yuya Nishihara <yuya@tcha.org>
parents: 44203
diff changeset
    63
        self.inner(py).borrow_mut().delete_path(
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    64
            HgPath::new(path.extract::<PyBytes>(py)?.data(py)),
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    65
        )
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    66
            .and(Ok(py.None()))
50534
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    67
            .map_err(|e|
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    68
                        PyErr::new::<exc::ValueError, _>(
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    69
                            py,
43788
1fe2e574616e rust-dirs: address failing tests for `dirs` impl with a temporary fix
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43430
diff changeset
    70
                            e.to_string(),
50534
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    71
                        )
6a019a037085 cleanup: simplify code
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 50532
diff changeset
    72
            )
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    73
    }
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    74
    def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
44233
281642cd1d04 rust-cpython: rename inner_shared() to inner()
Yuya Nishihara <yuya@tcha.org>
parents: 44203
diff changeset
    75
        let leaked_ref = self.inner(py).leak_immutable();
42891
5ccc08d02280 rust-cpython: leverage py_shared_iterator::from_inner() where appropriate
Yuya Nishihara <yuya@tcha.org>
parents: 42889
diff changeset
    76
        DirsMultisetKeysIterator::from_inner(
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    77
            py,
43285
ffc1fbd7d1f5 rust-cpython: make PyLeakedRef operations relatively safe
Yuya Nishihara <yuya@tcha.org>
parents: 43284
diff changeset
    78
            unsafe { leaked_ref.map(py, |o| o.iter()) },
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    79
        )
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    80
    }
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    81
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    82
    def __contains__(&self, item: PyObject) -> PyResult<bool> {
44233
281642cd1d04 rust-cpython: rename inner_shared() to inner()
Yuya Nishihara <yuya@tcha.org>
parents: 44203
diff changeset
    83
        Ok(self.inner(py).borrow().contains(HgPath::new(
49914
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48021
diff changeset
    84
            item.extract::<PyBytes>(py)?.data(py),
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    85
        )))
42537
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    86
    }
ce94f9622acd rust-dirstate: add "dirs" rust-cpython binding
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42408
diff changeset
    87
});
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    88
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    89
impl Dirs {
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    90
    pub fn from_inner(py: Python, d: DirsMultiset) -> PyResult<Self> {
44234
bad4e7b361d2 rust-cpython: switch to upstreamed version of PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents: 44233
diff changeset
    91
        Self::create_instance(py, d)
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    92
    }
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    93
42957
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    94
    fn translate_key(
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    95
        py: Python,
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    96
        res: &HgPathBuf,
7a01778bc7b7 rust-hgpath: replace all paths and filenames with HgPath/HgPathBuf
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42891
diff changeset
    97
    ) -> PyResult<Option<PyBytes>> {
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44234
diff changeset
    98
        Ok(Some(PyBytes::new(py, res.as_bytes())))
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
    99
    }
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   100
}
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   101
42889
ea91a126c803 rust-cpython: rename py_shared_iterator_impl to py_shared_iterator
Yuya Nishihara <yuya@tcha.org>
parents: 42887
diff changeset
   102
py_shared_iterator!(
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   103
    DirsMultisetKeysIterator,
44234
bad4e7b361d2 rust-cpython: switch to upstreamed version of PySharedRefCell
Yuya Nishihara <yuya@tcha.org>
parents: 44233
diff changeset
   104
    UnsafePyLeaked<DirsMultisetIter<'static>>,
42752
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   105
    Dirs::translate_key,
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   106
    Option<PyBytes>
30320c7bf79f rust-cpython: add macro for sharing references
Rapha?l Gom?s <rgomes@octobus.net>
parents: 42750
diff changeset
   107
);