rust/hg-cpython/src/dirstate/status.rs
author Pierre-Yves David <pierre-yves.david@octobus.net>
Thu, 02 Jan 2025 14:50:06 +0100
changeset 52592 87ceb51d124c
parent 52303 22d24f6d6411
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:
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     1
// status.rs
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     2
//
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2019, Raphaël Gomès <rgomes@octobus.net>
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     4
//
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     7
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
     8
//! Bindings for the `hg::status` module provided by the
43431
21a1b2094649 rust-cpython: run cargo fmt
Yuya Nishihara <yuya@tcha.org>
parents: 43273
diff changeset
     9
//! `hg-core` crate. From Python, this will be seen as
21a1b2094649 rust-cpython: run cargo fmt
Yuya Nishihara <yuya@tcha.org>
parents: 43273
diff changeset
    10
//! `rustext.dirstate.status`.
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    11
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    12
use crate::{dirstate::DirstateMap, exceptions::FallbackError};
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    13
use cpython::{
51599
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
    14
    exc::ValueError, ObjectProtocol, PyBool, PyBytes, PyErr, PyList, PyObject,
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    15
    PyResult, PyTuple, Python, PythonObject, ToPyObject,
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    16
};
52300
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51622
diff changeset
    17
use hg::dirstate::status::{
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51622
diff changeset
    18
    BadMatch, DirstateStatus, StatusError, StatusOptions, StatusPath,
04b9a56c2d25 rust-lib: only export very common types to the top of the crate
Rapha?l Gom?s <rgomes@octobus.net>
parents: 51622
diff changeset
    19
};
52303
22d24f6d6411 rust-lib: remove exports for not too common pattern-related types
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52302
diff changeset
    20
use hg::filepatterns::{
22d24f6d6411 rust-lib: remove exports for not too common pattern-related types
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52302
diff changeset
    21
    parse_pattern_syntax_kind, IgnorePattern, PatternError, PatternFileWarning,
22d24f6d6411 rust-lib: remove exports for not too common pattern-related types
Rapha?l Gom?s <rgomes@octobus.net>
parents: 52302
diff changeset
    22
};
49479
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
    23
use hg::matchers::{
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
    24
    DifferenceMatcher, IntersectionMatcher, Matcher, NeverMatcher,
51600
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
    25
    PatternMatcher, UnionMatcher,
49479
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
    26
};
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
    27
use hg::{
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    28
    matchers::{AlwaysMatcher, FileMatcher, IncludeMatcher},
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    29
    utils::{
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    30
        files::{get_bytes_from_path, get_path_from_bytes},
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    31
        hg_path::{HgPath, HgPathBuf},
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    32
    },
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
    33
};
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
    34
use std::borrow::Borrow;
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    35
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    36
fn collect_status_path_list(py: Python, paths: &[StatusPath<'_>]) -> PyList {
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    37
    collect_pybytes_list(py, paths.iter().map(|item| &*item.path))
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    38
}
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    39
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    40
/// This will be useless once trait impls for collection are added to `PyBytes`
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    41
/// upstream.
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    42
fn collect_pybytes_list(
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    43
    py: Python,
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    44
    iter: impl Iterator<Item = impl AsRef<HgPath>>,
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    45
) -> PyList {
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    46
    let list = PyList::new(py, &[]);
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    47
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
    48
    for path in iter {
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    49
        list.append(
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    50
            py,
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    51
            PyBytes::new(py, path.as_ref().as_bytes()).into_object(),
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    52
        )
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    53
    }
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    54
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    55
    list
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    56
}
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
    57
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    58
fn collect_bad_matches(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    59
    py: Python,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    60
    collection: &[(impl AsRef<HgPath>, BadMatch)],
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    61
) -> PyResult<PyList> {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    62
    let list = PyList::new(py, &[]);
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    63
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    64
    let os = py.import("os")?;
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    65
    let get_error_message = |code: i32| -> PyResult<_> {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    66
        os.call(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    67
            py,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    68
            "strerror",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    69
            PyTuple::new(py, &[code.to_py_object(py).into_object()]),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    70
            None,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    71
        )
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    72
    };
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    73
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    74
    for (path, bad_match) in collection.iter() {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    75
        let message = match bad_match {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    76
            BadMatch::OsError(code) => get_error_message(*code)?,
49914
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49479
diff changeset
    77
            BadMatch::BadType(bad_type) => {
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49479
diff changeset
    78
                format!("unsupported file type (type is {})", bad_type)
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49479
diff changeset
    79
                    .to_py_object(py)
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49479
diff changeset
    80
                    .into_object()
58074252db3c rust: run `cargo clippy`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49479
diff changeset
    81
            }
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    82
        };
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    83
        list.append(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    84
            py,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    85
            (PyBytes::new(py, path.as_ref().as_bytes()), message)
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    86
                .to_py_object(py)
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    87
                .into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    88
        )
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    89
    }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    90
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    91
    Ok(list)
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    92
}
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    93
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    94
fn handle_fallback(py: Python, err: StatusError) -> PyErr {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    95
    match err {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
    96
        StatusError::Pattern(e) => {
44572
245aec57d76a rust-status: add trace-level logging for Rust status fallback for debugging
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44529
diff changeset
    97
            let as_string = e.to_string();
245aec57d76a rust-status: add trace-level logging for Rust status fallback for debugging
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44529
diff changeset
    98
            log::trace!("Rust status fallback: `{}`", &as_string);
245aec57d76a rust-status: add trace-level logging for Rust status fallback for debugging
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44529
diff changeset
    99
245aec57d76a rust-status: add trace-level logging for Rust status fallback for debugging
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44529
diff changeset
   100
            PyErr::new::<FallbackError, _>(py, &as_string)
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   101
        }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   102
        e => PyErr::new::<ValueError, _>(py, e.to_string()),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   103
    }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   104
}
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   105
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   106
pub fn status_wrapper(
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   107
    py: Python,
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   108
    dmap: DirstateMap,
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   109
    matcher: PyObject,
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   110
    root_dir: PyObject,
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   111
    ignore_files: PyList,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   112
    check_exec: bool,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   113
    list_clean: bool,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   114
    list_ignored: bool,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   115
    list_unknown: bool,
44839
01afda7e7d6c rust-hg-cpython: update status bridge with the new `traversedir` support
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44597
diff changeset
   116
    collect_traversed_dirs: bool,
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   117
) -> PyResult<PyTuple> {
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   118
    let bytes = root_dir.extract::<PyBytes>(py)?;
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   119
    let root_dir = get_path_from_bytes(bytes.data(py));
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   120
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   121
    let dmap: DirstateMap = dmap.to_py_object(py);
47112
d5956136d19d dirstate-tree: Give to `status()` mutable access to the `DirstateMap`
Simon Sapin <simon.sapin@octobus.net>
parents: 47110
diff changeset
   122
    let mut dmap = dmap.get_inner_mut(py);
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   123
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   124
    let ignore_files: PyResult<Vec<_>> = ignore_files
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   125
        .iter(py)
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   126
        .map(|b| {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   127
            let file = b.extract::<PyBytes>(py)?;
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   128
            Ok(get_path_from_bytes(file.data(py)).to_owned())
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   129
        })
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   130
        .collect();
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   131
    let ignore_files = ignore_files?;
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   132
    // The caller may call `copymap.items()` separately
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   133
    let list_copies = false;
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   134
49000
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   135
    let after_status = |res: Result<(DirstateStatus<'_>, _), StatusError>| {
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   136
        let (status_res, warnings) =
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   137
            res.map_err(|e| handle_fallback(py, e))?;
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   138
        build_response(py, status_res, warnings)
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   139
    };
dd6b67d5c256 rust: fix unsound `OwningDirstateMap`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 48744
diff changeset
   140
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   141
    let matcher = extract_matcher(py, matcher)?;
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   142
    dmap.with_status(
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   143
        &*matcher,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   144
        root_dir.to_path_buf(),
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   145
        ignore_files,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   146
        StatusOptions {
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   147
            check_exec,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   148
            list_clean,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   149
            list_ignored,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   150
            list_unknown,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   151
            list_copies,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   152
            collect_traversed_dirs,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   153
        },
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   154
        after_status,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   155
    )
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   156
}
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   157
51601
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   158
fn collect_kindpats(
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   159
    py: Python,
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   160
    matcher: PyObject,
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   161
) -> PyResult<Vec<IgnorePattern>> {
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   162
    matcher
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   163
        .getattr(py, "_kindpats")?
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   164
        .iter(py)?
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   165
        .map(|k| {
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   166
            let k = k?;
51602
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   167
            let syntax = parse_pattern_syntax_kind(
e4b9f8a74d5f match: simplify the rust-side file pattern kind parsing
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51601
diff changeset
   168
                k.get_item(py, 0)?.extract::<PyBytes>(py)?.data(py),
51601
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   169
            )
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   170
            .map_err(|e| handle_fallback(py, StatusError::Pattern(e)))?;
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   171
            let pattern = k.get_item(py, 1)?.extract::<PyBytes>(py)?;
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   172
            let pattern = pattern.data(py);
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   173
            let source = k.get_item(py, 2)?.extract::<PyBytes>(py)?;
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   174
            let source = get_path_from_bytes(source.data(py));
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   175
            let new = IgnorePattern::new(syntax, pattern, source);
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   176
            Ok(new)
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   177
        })
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   178
        .collect()
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   179
}
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   180
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   181
/// Transform a Python matcher into a Rust matcher.
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   182
fn extract_matcher(
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   183
    py: Python,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   184
    matcher: PyObject,
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   185
) -> PyResult<Box<dyn Matcher + Sync>> {
51599
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   186
    let tampered = matcher
51622
aa23b19e6da4 match: make `was_tampered_with` work recursively
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51602
diff changeset
   187
        .call_method(py, "was_tampered_with_nonrec", PyTuple::empty(py), None)?
51599
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   188
        .extract::<PyBool>(py)?
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   189
        .is_true();
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   190
    if tampered {
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   191
        return Err(handle_fallback(
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   192
            py,
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   193
            StatusError::Pattern(PatternError::UnsupportedSyntax(
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   194
                "Pattern matcher was tampered with!".to_string(),
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   195
            )),
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   196
        ));
68929cf3c0c6 match: avoid rust fast path if the matcher was tampered with
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51117
diff changeset
   197
    };
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   198
    match matcher.get_type(py).name(py).borrow() {
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   199
        "alwaysmatcher" => Ok(Box::new(AlwaysMatcher)),
49351
97dcd6906e6f rust-dirstate: add support for nevermatcher
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49350
diff changeset
   200
        "nevermatcher" => Ok(Box::new(NeverMatcher)),
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   201
        "exactmatcher" => {
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   202
            let files = matcher.call_method(
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   203
                py,
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   204
                "files",
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   205
                PyTuple::new(py, &[]),
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   206
                None,
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   207
            )?;
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   208
            let files: PyList = files.cast_into(py)?;
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   209
            let files: PyResult<Vec<HgPathBuf>> = files
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   210
                .iter(py)
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   211
                .map(|f| {
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   212
                    Ok(HgPathBuf::from_bytes(
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   213
                        f.extract::<PyBytes>(py)?.data(py),
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   214
                    ))
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   215
                })
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   216
                .collect();
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43818
diff changeset
   217
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   218
            let files = files?;
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   219
            let file_matcher = FileMatcher::new(files)
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   220
                .map_err(|e| PyErr::new::<ValueError, _>(py, e.to_string()))?;
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   221
            Ok(Box::new(file_matcher))
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   222
        }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   223
        "includematcher" => {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   224
            // Get the patterns from Python even though most of them are
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   225
            // redundant with those we will parse later on, as they include
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   226
            // those passed from the command line.
51601
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   227
            let ignore_patterns = collect_kindpats(py, matcher)?;
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   228
47379
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47350
diff changeset
   229
            let matcher = IncludeMatcher::new(ignore_patterns)
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47350
diff changeset
   230
                .map_err(|e| handle_fallback(py, e.into()))?;
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   231
49346
75119bbee3d1 hg-cpython: refactor matcher transformation logic
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49345
diff changeset
   232
            Ok(Box::new(matcher))
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   233
        }
49348
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   234
        "unionmatcher" => {
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   235
            let matchers: PyResult<Vec<_>> = matcher
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   236
                .getattr(py, "_matchers")?
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   237
                .iter(py)?
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   238
                .map(|py_matcher| extract_matcher(py, py_matcher?))
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   239
                .collect();
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   240
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   241
            Ok(Box::new(UnionMatcher::new(matchers?)))
0043c7aa3250 rust-dirstate: add `unionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49346
diff changeset
   242
        }
49350
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   243
        "intersectionmatcher" => {
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   244
            let m1 = extract_matcher(py, matcher.getattr(py, "_m1")?)?;
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   245
            let m2 = extract_matcher(py, matcher.getattr(py, "_m2")?)?;
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   246
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   247
            Ok(Box::new(IntersectionMatcher::new(m1, m2)))
0b00998e336a rust-dirstate: add `intersectionmatcher` to the allowed matchers
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49348
diff changeset
   248
        }
49479
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   249
        "differencematcher" => {
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   250
            let m1 = extract_matcher(py, matcher.getattr(py, "_m1")?)?;
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   251
            let m2 = extract_matcher(py, matcher.getattr(py, "_m2")?)?;
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   252
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   253
            Ok(Box::new(DifferenceMatcher::new(m1, m2)))
6193e846cb65 rust-status: expose DifferenceMatcher from Rust to Python
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49351
diff changeset
   254
        }
51600
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   255
        "patternmatcher" => {
51601
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   256
            let patterns = collect_kindpats(py, matcher)?;
51600
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   257
51601
32ba01b5669d match: share code between includematcher and patternmatcher
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51600
diff changeset
   258
            let matcher = PatternMatcher::new(patterns)
51600
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   259
                .map_err(|e| handle_fallback(py, e.into()))?;
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   260
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   261
            Ok(Box::new(matcher))
a2afa35641c9 matchers: support patternmatcher in rust
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents: 51599
diff changeset
   262
        }
49344
44319aa4a2a4 hg-cpython: fallback when encountering an unknown matcher
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49000
diff changeset
   263
        e => Err(PyErr::new::<FallbackError, _>(
44973
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44839
diff changeset
   264
            py,
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44839
diff changeset
   265
            format!("Unsupported matcher {}", e),
26114bd6ec60 rust: do a clippy pass
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44839
diff changeset
   266
        )),
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   267
    }
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   268
}
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   269
43916
6a88ced33c40 rust-dirstate-status: update bridge for new rust version of `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 43915
diff changeset
   270
fn build_response(
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   271
    py: Python,
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44232
diff changeset
   272
    status_res: DirstateStatus,
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   273
    warnings: Vec<PatternFileWarning>,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   274
) -> PyResult<PyTuple> {
48454
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   275
    let modified = collect_status_path_list(py, &status_res.modified);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   276
    let added = collect_status_path_list(py, &status_res.added);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   277
    let removed = collect_status_path_list(py, &status_res.removed);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   278
    let deleted = collect_status_path_list(py, &status_res.deleted);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   279
    let clean = collect_status_path_list(py, &status_res.clean);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   280
    let ignored = collect_status_path_list(py, &status_res.ignored);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   281
    let unknown = collect_status_path_list(py, &status_res.unknown);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   282
    let unsure = collect_status_path_list(py, &status_res.unsure);
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   283
    let bad = collect_bad_matches(py, &status_res.bad)?;
473af5cbc209 rhg: Add support for `rhg status --copies`
Simon Sapin <simon.sapin@octobus.net>
parents: 48391
diff changeset
   284
    let traversed = collect_pybytes_list(py, status_res.traversed.iter());
47350
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
   285
    let dirty = status_res.dirty.to_py_object(py);
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   286
    let py_warnings = PyList::new(py, &[]);
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   287
    for warning in warnings.iter() {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   288
        // We use duck-typing on the Python side for dispatch, good enough for
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   289
        // now.
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   290
        match warning {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   291
            PatternFileWarning::InvalidSyntax(file, syn) => {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   292
                py_warnings.append(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   293
                    py,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   294
                    (
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49914
diff changeset
   295
                        PyBytes::new(py, &get_bytes_from_path(file)),
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   296
                        PyBytes::new(py, syn),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   297
                    )
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   298
                        .to_py_object(py)
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   299
                        .into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   300
                );
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   301
            }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   302
            PatternFileWarning::NoSuchFile(file) => py_warnings.append(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   303
                py,
51117
532e74ad3ff6 rust: run a clippy pass with the latest stable version
Rapha?l Gom?s <rgomes@octobus.net>
parents: 49914
diff changeset
   304
                PyBytes::new(py, &get_bytes_from_path(file)).into_object(),
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   305
            ),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   306
        }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   307
    }
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   308
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   309
    Ok(PyTuple::new(
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   310
        py,
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   311
        &[
47110
9c6b458a08e1 rust: Move "lookup" a.k.a. "unsure" paths into `DirstateStatus` struct
Simon Sapin <simon.sapin@octobus.net>
parents: 47093
diff changeset
   312
            unsure.into_object(),
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   313
            modified.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   314
            added.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   315
            removed.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   316
            deleted.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   317
            clean.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   318
            ignored.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   319
            unknown.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   320
            py_warnings.into_object(),
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   321
            bad.into_object(),
44839
01afda7e7d6c rust-hg-cpython: update status bridge with the new `traversedir` support
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44597
diff changeset
   322
            traversed.into_object(),
47350
04d1f17f49e7 dirstate-v2: Write .hg/dirstate back to disk on directory cache changes
Simon Sapin <simon.sapin@octobus.net>
parents: 47112
diff changeset
   323
            dirty.into_object(),
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   324
        ][..],
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Rapha?l Gom?s <rgomes@octobus.net>
parents: 44525
diff changeset
   325
    ))
43273
478d0b1bf0c5 rust-dirstate-status: rust-cpython bindings for `dirstate.status`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
   326
}