view rust/hg-cpython/src/dirstate/non_normal_entries.rs @ 44327:71e13cfd6154 stable

rust-dirstatemap: add `NonNormalEntries` class This fix introduces the same encapsulation as the `copymap`. There is no easy way of doing this any better for now. `hg up -r null && time HGRCPATH= HGMODULEPOLICY=rust+c hg up tip` on Mozilla Central, (not super recent, but it doesn't matter): Before: 7:44,08 total After: 1:03,23 total Pretty brutal regression! This is a graft on stable of cf1f8660e568 Differential Revision: https://phab.mercurial-scm.org/D8111
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 12 Feb 2020 23:23:59 +0100
parents
children 8ac5726d695d
line wrap: on
line source

// non_normal_other_parent_entries.rs
//
// Copyright 2020 Raphaël Gomès <rgomes@octobus.net>
//
// This software may be used and distributed according to the terms of the
// GNU General Public License version 2 or any later version.

use cpython::{
    exc::NotImplementedError, CompareOp, ObjectProtocol, PyErr, PyList,
    PyObject, PyResult, PyString, Python, PythonObject, ToPyObject,
};

use crate::dirstate::DirstateMap;

py_class!(pub class NonNormalEntries |py| {
    data dmap: DirstateMap;

    def __contains__(&self, key: PyObject) -> PyResult<bool> {
        self.dmap(py).non_normal_entries_contains(py, key)
    }
    def remove(&self, key: PyObject) -> PyResult<PyObject> {
        self.dmap(py).non_normal_entries_remove(py, key)
    }
    def union(&self, other: PyObject) -> PyResult<PyList> {
        self.dmap(py).non_normal_entries_union(py, other)
    }
    def __richcmp__(&self, other: PyObject, op: CompareOp) -> PyResult<bool> {
        match op {
            CompareOp::Eq => self.is_equal_to(py, other),
            CompareOp::Ne => Ok(!self.is_equal_to(py, other)?),
            _ => Err(PyErr::new::<NotImplementedError, _>(py, ""))
        }
    }
    def __repr__(&self) -> PyResult<PyString> {
        self.dmap(py).non_normal_entries_display(py)
    }
});

impl NonNormalEntries {
    pub fn from_inner(py: Python, dm: DirstateMap) -> PyResult<Self> {
        Self::create_instance(py, dm)
    }

    fn is_equal_to(&self, py: Python, other: PyObject) -> PyResult<bool> {
        for item in other.iter(py)? {
            if !self.dmap(py).non_normal_entries_contains(py, item?)? {
                return Ok(false);
            }
        }
        Ok(true)
    }
}