rust/hg-core/src/dirstate/status.rs
author Raphaël Gomès <rgomes@octobus.net>
Wed, 10 Feb 2021 21:46:29 +0100
branchstable
changeset 46489 fb6eca7b8c63
parent 46054 fd47483f1645
child 46494 d67732a4b58a
permissions -rw-r--r--
rust-status: honor matcher when using the dirstate-only fast-path (issue6483) Differential Revision: https://phab.mercurial-scm.org/D9977
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// status.rs
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `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
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
//! Rust implementation of dirstate.status (dirstate.py).
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
//! It is currently missing a lot of functionality compared to the Python one
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
//! and will only be triggered in narrow cases.
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
    12
#[cfg(feature = "dirstate-tree")]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
    13
use crate::dirstate::dirstate_tree::iter::StatusShortcut;
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
    14
#[cfg(not(feature = "dirstate-tree"))]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
    15
use crate::utils::path_auditor::PathAuditor;
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
    16
use crate::{
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
    17
    dirstate::SIZE_FROM_OTHER_PARENT,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    18
    filepatterns::PatternFileWarning,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    19
    matchers::{get_ignore_function, Matcher, VisitChildrenSet},
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
    20
    utils::{
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    21
        files::{find_dirs, HgMetadata},
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
    22
        hg_path::{
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
    23
            hg_path_to_path_buf, os_string_to_hg_path_buf, HgPath, HgPathBuf,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    24
            HgPathError,
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
    25
        },
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
    26
    },
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
    27
    CopyMap, DirstateEntry, DirstateMap, EntryState, FastHashMap,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    28
    PatternError,
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
    29
};
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    30
use lazy_static::lazy_static;
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
    31
use micro_timer::timed;
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
use rayon::prelude::*;
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    33
use std::{
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    34
    borrow::Cow,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    35
    collections::HashSet,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    36
    fs::{read_dir, DirEntry},
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    37
    io::ErrorKind,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    38
    ops::Deref,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
    39
    path::{Path, PathBuf},
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
    40
};
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    42
/// Wrong type of file from a `BadMatch`
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    43
/// Note: a lot of those don't exist on all platforms.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
    44
#[derive(Debug, Copy, Clone)]
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    45
pub enum BadType {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    46
    CharacterDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    47
    BlockDevice,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    48
    FIFO,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    49
    Socket,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    50
    Directory,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    51
    Unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    52
}
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    53
44529
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    54
impl ToString for BadType {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    55
    fn to_string(&self) -> String {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    56
        match self {
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    57
            BadType::CharacterDevice => "character device",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    58
            BadType::BlockDevice => "block device",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    59
            BadType::FIFO => "fifo",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    60
            BadType::Socket => "socket",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    61
            BadType::Directory => "directory",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    62
            BadType::Unknown => "unknown",
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
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: 44528
diff changeset
    64
        .to_string()
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    65
    }
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    66
}
f96b28aa4b79 rust-status: update rust-cpython bridge to account for the changes in core
Raphaël Gomès <rgomes@octobus.net>
parents: 44528
diff changeset
    67
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    68
/// Was explicitly matched but cannot be found/accessed
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
    69
#[derive(Debug, Copy, Clone)]
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    70
pub enum BadMatch {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    71
    OsError(i32),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    72
    BadType(BadType),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    73
}
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    74
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
    75
/// Enum used to dispatch new status entries into the right collections.
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    76
/// Is similar to `crate::EntryState`, but represents the transient state of
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    77
/// entries during the lifetime of a command.
44536
f8a9922a02cb rust-status: move to recursive traversal to prepare for parallel traversal
Raphaël Gomès <rgomes@octobus.net>
parents: 44535
diff changeset
    78
#[derive(Debug, Copy, Clone)]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
    79
pub enum Dispatch {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    80
    Unsure,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    81
    Modified,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    82
    Added,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    83
    Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    84
    Deleted,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    85
    Clean,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    86
    Unknown,
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    87
    Ignored,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    88
    /// Empty dispatch, the file is not worth listing
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    89
    None,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    90
    /// Was explicitly matched but cannot be found/accessed
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    91
    Bad(BadMatch),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    92
    Directory {
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    93
        /// True if the directory used to be a file in the dmap so we can say
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    94
        /// that it's been removed.
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    95
        was_file: bool,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
    96
    },
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    97
}
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
    98
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
    99
type IoResult<T> = std::io::Result<T>;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   100
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
   101
/// `Box<dyn Trait>` is syntactic sugar for `Box<dyn Trait, 'static>`, so add
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
   102
/// an explicit lifetime here to not fight `'static` bounds "out of nowhere".
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
   103
type IgnoreFnType<'a> = Box<dyn for<'r> Fn(&'r HgPath) -> bool + Sync + 'a>;
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
   104
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   105
/// We have a good mix of owned (from directory traversal) and borrowed (from
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   106
/// the dirstate/explicit) paths, this comes up a lot.
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
   107
pub type HgPathCow<'a> = Cow<'a, HgPath>;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   108
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   109
/// A path with its computed ``Dispatch`` information
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   110
type DispatchedPath<'a> = (HgPathCow<'a>, Dispatch);
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   111
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   112
/// The conversion from `HgPath` to a real fs path failed.
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   113
/// `22` is the error code for "Invalid argument"
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   114
const INVALID_PATH_DISPATCH: Dispatch = Dispatch::Bad(BadMatch::OsError(22));
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   115
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   116
/// Dates and times that are outside the 31-bit signed range are compared
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   117
/// modulo 2^31. This should prevent hg from behaving badly with very large
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   118
/// files or corrupt dates while still having a high probability of detecting
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   119
/// changes. (issue2608)
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   120
/// TODO I haven't found a way of having `b` be `Into<i32>`, since `From<u64>`
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   121
/// is not defined for `i32`, and there is no `As` trait. This forces the
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   122
/// caller to cast `b` as `i32`.
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   123
fn mod_compare(a: i32, b: i32) -> bool {
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   124
    a & i32::max_value() != b & i32::max_value()
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   125
}
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   126
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   127
/// Return a sorted list containing information about the entries
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   128
/// in the directory.
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   129
///
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   130
/// * `skip_dot_hg` - Return an empty vec if `path` contains a `.hg` directory
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   131
fn list_directory(
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   132
    path: impl AsRef<Path>,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   133
    skip_dot_hg: bool,
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   134
) -> std::io::Result<Vec<(HgPathBuf, DirEntry)>> {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   135
    let mut results = vec![];
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   136
    let entries = read_dir(path.as_ref())?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   137
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   138
    for entry in entries {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   139
        let entry = entry?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   140
        let filename = os_string_to_hg_path_buf(entry.file_name())?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   141
        let file_type = entry.file_type()?;
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   142
        if skip_dot_hg && filename.as_bytes() == b".hg" && file_type.is_dir() {
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   143
            return Ok(vec![]);
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   144
        } else {
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
   145
            results.push((filename, entry))
44523
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   146
        }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   147
    }
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   148
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   149
    results.sort_unstable_by_key(|e| e.0.clone());
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   150
    Ok(results)
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   151
}
0d97bcb3cee9 rust-status: add util for listing a directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44193
diff changeset
   152
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   153
/// The file corresponding to the dirstate entry was found on the filesystem.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   154
fn dispatch_found(
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   155
    filename: impl AsRef<HgPath>,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   156
    entry: DirstateEntry,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   157
    metadata: HgMetadata,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   158
    copy_map: &CopyMap,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   159
    options: StatusOptions,
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   160
) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   161
    let DirstateEntry {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   162
        state,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   163
        mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   164
        mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   165
        size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   166
    } = entry;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   167
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   168
    let HgMetadata {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   169
        st_mode,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   170
        st_size,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   171
        st_mtime,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   172
        ..
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   173
    } = metadata;
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   174
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   175
    match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   176
        EntryState::Normal => {
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   177
            let size_changed = mod_compare(size, st_size as i32);
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   178
            let mode_changed =
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   179
                (mode ^ st_mode as i32) & 0o100 != 0o000 && options.check_exec;
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   180
            let metadata_changed = size >= 0 && (size_changed || mode_changed);
43605
8210c3f46912 rust: introduce SIZE_FROM_OTHER_PARENT constant
Raphaël Gomès <rgomes@octobus.net>
parents: 43604
diff changeset
   181
            let other_parent = size == SIZE_FROM_OTHER_PARENT;
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
   182
43604
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   183
            if metadata_changed
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   184
                || other_parent
51cd86735608 rust-status: refactor dispatch case for normal files
Raphaël Gomès <rgomes@octobus.net>
parents: 43603
diff changeset
   185
                || copy_map.contains_key(filename.as_ref())
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   186
            {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   187
                Dispatch::Modified
44973
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
   188
            } else if mod_compare(mtime, st_mtime as i32)
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
   189
                || st_mtime == options.last_normal_time
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44926
diff changeset
   190
            {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   191
                // the file may have just been marked as normal and
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   192
                // it may have changed in the same second without
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   193
                // changing its size. This can happen if we quickly
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   194
                // do multiple commits. Force lookup, so we don't
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   195
                // miss such a racy file change.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   196
                Dispatch::Unsure
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   197
            } else if options.list_clean {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   198
                Dispatch::Clean
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   199
            } else {
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   200
                Dispatch::None
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   201
            }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   202
        }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   203
        EntryState::Merged => Dispatch::Modified,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   204
        EntryState::Added => Dispatch::Added,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   205
        EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   206
        EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   207
    }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   208
}
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   209
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   210
/// The file corresponding to this Dirstate entry is missing.
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   211
fn dispatch_missing(state: EntryState) -> Dispatch {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   212
    match state {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   213
        // File was removed from the filesystem during commands
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   214
        EntryState::Normal | EntryState::Merged | EntryState::Added => {
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   215
            Dispatch::Deleted
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   216
        }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   217
        // File was removed, everything is normal
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   218
        EntryState::Removed => Dispatch::Removed,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   219
        // File is unknown to Mercurial, everything is normal
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   220
        EntryState::Unknown => Dispatch::Unknown,
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   221
    }
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   222
}
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   223
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   224
fn dispatch_os_error(e: &std::io::Error) -> Dispatch {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   225
    Dispatch::Bad(BadMatch::OsError(
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   226
        e.raw_os_error().expect("expected real OS error"),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   227
    ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   228
}
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   229
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   230
lazy_static! {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   231
    static ref DEFAULT_WORK: HashSet<&'static HgPath> = {
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   232
        let mut h = HashSet::new();
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   233
        h.insert(HgPath::new(b""));
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   234
        h
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   235
    };
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   236
}
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   237
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   238
#[derive(Debug, Copy, Clone)]
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   239
pub struct StatusOptions {
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   240
    /// Remember the most recent modification timeslot for status, to make
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   241
    /// sure we won't miss future size-preserving file content modifications
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   242
    /// that happen within the same timeslot.
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   243
    pub last_normal_time: i64,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   244
    /// Whether we are on a filesystem with UNIX-like exec flags
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   245
    pub check_exec: bool,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   246
    pub list_clean: bool,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
   247
    pub list_unknown: bool,
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
   248
    pub list_ignored: bool,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   249
    /// Whether to collect traversed dirs for applying a callback later.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   250
    /// Used by `hg purge` for example.
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   251
    pub collect_traversed_dirs: bool,
44527
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
   252
}
1debb5894b39 rust-status: add function for sequential traversal of the working directory
Raphaël Gomès <rgomes@octobus.net>
parents: 44526
diff changeset
   253
44562
ece43c79333e rust-core: add missing `Debug` traits
Raphaël Gomès <rgomes@octobus.net>
parents: 44541
diff changeset
   254
#[derive(Debug)]
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
   255
pub struct DirstateStatus<'a> {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   256
    pub modified: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   257
    pub added: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   258
    pub removed: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   259
    pub deleted: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   260
    pub clean: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   261
    pub ignored: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   262
    pub unknown: Vec<HgPathCow<'a>>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   263
    pub bad: Vec<(HgPathCow<'a>, BadMatch)>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   264
    /// Only filled if `collect_traversed_dirs` is `true`
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   265
    pub traversed: Vec<HgPathBuf>,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   266
}
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   267
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   268
#[derive(Debug)]
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   269
pub enum StatusError {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   270
    /// Generic IO error
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   271
    IO(std::io::Error),
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   272
    /// An invalid path that cannot be represented in Mercurial was found
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   273
    Path(HgPathError),
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   274
    /// An invalid "ignore" pattern was found
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   275
    Pattern(PatternError),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   276
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   277
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   278
pub type StatusResult<T> = Result<T, StatusError>;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   279
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   280
impl From<PatternError> for StatusError {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   281
    fn from(e: PatternError) -> Self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   282
        StatusError::Pattern(e)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   283
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   284
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   285
impl From<HgPathError> for StatusError {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   286
    fn from(e: HgPathError) -> Self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   287
        StatusError::Path(e)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   288
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   289
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   290
impl From<std::io::Error> for StatusError {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   291
    fn from(e: std::io::Error) -> Self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   292
        StatusError::IO(e)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   293
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   294
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   295
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   296
impl ToString for StatusError {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   297
    fn to_string(&self) -> String {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   298
        match self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   299
            StatusError::IO(e) => e.to_string(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   300
            StatusError::Path(e) => e.to_string(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   301
            StatusError::Pattern(e) => e.to_string(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   302
        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   303
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   304
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   305
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   306
/// Gives information about which files are changed in the working directory
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   307
/// and how, compared to the revision we're based on
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   308
pub struct Status<'a, M: Matcher + Sync> {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   309
    dmap: &'a DirstateMap,
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
   310
    pub(crate) matcher: &'a M,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   311
    root_dir: PathBuf,
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
   312
    pub(crate) options: StatusOptions,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   313
    ignore_fn: IgnoreFnType<'a>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   314
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   315
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   316
impl<'a, M> Status<'a, M>
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   317
where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   318
    M: Matcher + Sync,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   319
{
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   320
    pub fn new(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   321
        dmap: &'a DirstateMap,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   322
        matcher: &'a M,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   323
        root_dir: PathBuf,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   324
        ignore_files: Vec<PathBuf>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   325
        options: StatusOptions,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   326
    ) -> StatusResult<(Self, Vec<PatternFileWarning>)> {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   327
        // Needs to outlive `dir_ignore_fn` since it's captured.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   328
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   329
        let (ignore_fn, warnings): (IgnoreFnType, _) =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   330
            if options.list_ignored || options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   331
                get_ignore_function(ignore_files, &root_dir)?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   332
            } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   333
                (Box::new(|&_| true), vec![])
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   334
            };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   335
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   336
        Ok((
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   337
            Self {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   338
                dmap,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   339
                matcher,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   340
                root_dir,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   341
                options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   342
                ignore_fn,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   343
            },
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   344
            warnings,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   345
        ))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   346
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   347
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   348
    /// Is the path ignored?
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   349
    pub fn is_ignored(&self, path: impl AsRef<HgPath>) -> bool {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   350
        (self.ignore_fn)(path.as_ref())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   351
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   352
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   353
    /// Is the path or one of its ancestors ignored?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   354
    pub fn dir_ignore(&self, dir: impl AsRef<HgPath>) -> bool {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   355
        // Only involve ignore mechanism if we're listing unknowns or ignored.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   356
        if self.options.list_ignored || self.options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   357
            if self.is_ignored(&dir) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   358
                true
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   359
            } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   360
                for p in find_dirs(dir.as_ref()) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   361
                    if self.is_ignored(p) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   362
                        return true;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   363
                    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   364
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   365
                false
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   366
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   367
        } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   368
            true
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   369
        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   370
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   371
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   372
    /// Get stat data about the files explicitly specified by the matcher.
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   373
    /// Returns a tuple of the directories that need to be traversed and the
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   374
    /// files with their corresponding `Dispatch`.
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   375
    /// TODO subrepos
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   376
    #[timed]
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   377
    pub fn walk_explicit(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   378
        &self,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   379
        traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   380
    ) -> (Vec<DispatchedPath<'a>>, Vec<DispatchedPath<'a>>) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   381
        self.matcher
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   382
            .file_set()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   383
            .unwrap_or(&DEFAULT_WORK)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   384
            .par_iter()
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   385
            .flat_map(|&filename| -> Option<_> {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   386
                // TODO normalization
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   387
                let normalized = filename;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   388
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   389
                let buf = match hg_path_to_path_buf(normalized) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   390
                    Ok(x) => x,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   391
                    Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   392
                        return Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   393
                            Cow::Borrowed(normalized),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   394
                            INVALID_PATH_DISPATCH,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   395
                        ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   396
                    }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   397
                };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   398
                let target = self.root_dir.join(buf);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   399
                let st = target.symlink_metadata();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   400
                let in_dmap = self.dmap.get(normalized);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   401
                match st {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   402
                    Ok(meta) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   403
                        let file_type = meta.file_type();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   404
                        return if file_type.is_file() || file_type.is_symlink()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   405
                        {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   406
                            if let Some(entry) = in_dmap {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   407
                                return Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   408
                                    Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   409
                                    dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   410
                                        &normalized,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   411
                                        *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   412
                                        HgMetadata::from_metadata(meta),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   413
                                        &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   414
                                        self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   415
                                    ),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   416
                                ));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   417
                            }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   418
                            Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   419
                                Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   420
                                Dispatch::Unknown,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   421
                            ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   422
                        } else if file_type.is_dir() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   423
                            if self.options.collect_traversed_dirs {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   424
                                traversed_sender
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   425
                                    .send(normalized.to_owned())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   426
                                    .expect("receiver should outlive sender");
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   427
                            }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   428
                            Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   429
                                Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   430
                                Dispatch::Directory {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   431
                                    was_file: in_dmap.is_some(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   432
                                },
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   433
                            ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   434
                        } else {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   435
                            Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   436
                                Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   437
                                Dispatch::Bad(BadMatch::BadType(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   438
                                    // TODO do more than unknown
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   439
                                    // Support for all `BadType` variant
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   440
                                    // varies greatly between platforms.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   441
                                    // So far, no tests check the type and
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   442
                                    // this should be good enough for most
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   443
                                    // users.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   444
                                    BadType::Unknown,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   445
                                )),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   446
                            ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   447
                        };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   448
                    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   449
                    Err(_) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   450
                        if let Some(entry) = in_dmap {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   451
                            return Some((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   452
                                Cow::Borrowed(normalized),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   453
                                dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   454
                            ));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   455
                        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   456
                    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   457
                };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   458
                None
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   459
            })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   460
            .partition(|(_, dispatch)| match dispatch {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   461
                Dispatch::Directory { .. } => true,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   462
                _ => false,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   463
            })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   464
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   465
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   466
    /// Walk the working directory recursively to look for changes compared to
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   467
    /// the current `DirstateMap`.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   468
    ///
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   469
    /// This takes a mutable reference to the results to account for the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   470
    /// `extend` in timings
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   471
    #[timed]
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   472
    pub fn traverse(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   473
        &self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   474
        path: impl AsRef<HgPath>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   475
        old_results: &FastHashMap<HgPathCow<'a>, Dispatch>,
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   476
        results: &mut Vec<DispatchedPath<'a>>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   477
        traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   478
    ) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   479
        // The traversal is done in parallel, so use a channel to gather
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   480
        // entries. `crossbeam_channel::Sender` is `Sync`, while `mpsc::Sender`
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   481
        // is not.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   482
        let (files_transmitter, files_receiver) =
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   483
            crossbeam_channel::unbounded();
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   484
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   485
        self.traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   486
            &files_transmitter,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   487
            path,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   488
            &old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   489
            traversed_sender,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   490
        );
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   491
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   492
        // Disconnect the channel so the receiver stops waiting
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   493
        drop(files_transmitter);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   494
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   495
        let new_results = files_receiver
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   496
            .into_iter()
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   497
            .par_bridge()
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   498
            .map(|(f, d)| (Cow::Owned(f), d));
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   499
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   500
        results.par_extend(new_results);
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   501
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   502
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   503
    /// Dispatch a single entry (file, folder, symlink...) found during
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   504
    /// `traverse`. If the entry is a folder that needs to be traversed, it
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   505
    /// will be handled in a separate thread.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   506
    fn handle_traversed_entry<'b>(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   507
        &'a self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   508
        scope: &rayon::Scope<'b>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   509
        files_sender: &'b crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   510
        old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   511
        filename: HgPathBuf,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   512
        dir_entry: DirEntry,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   513
        traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   514
    ) -> IoResult<()>
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   515
    where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   516
        'a: 'b,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   517
    {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   518
        let file_type = dir_entry.file_type()?;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   519
        let entry_option = self.dmap.get(&filename);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   520
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   521
        if filename.as_bytes() == b".hg" {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   522
            // Could be a directory or a symlink
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   523
            return Ok(());
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   524
        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   525
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   526
        if file_type.is_dir() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   527
            self.handle_traversed_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   528
                scope,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   529
                files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   530
                old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   531
                entry_option,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   532
                filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   533
                traversed_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   534
            );
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   535
        } else if file_type.is_file() || file_type.is_symlink() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   536
            if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   537
                if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   538
                    || self.matcher.matches(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   539
                {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   540
                    let metadata = dir_entry.metadata()?;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   541
                    files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   542
                        .send((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   543
                            filename.to_owned(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   544
                            dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   545
                                &filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   546
                                *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   547
                                HgMetadata::from_metadata(metadata),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   548
                                &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   549
                                self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   550
                            ),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   551
                        ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   552
                        .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   553
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   554
            } else if (self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   555
                || self.matcher.matches(&filename))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   556
                && !self.is_ignored(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   557
            {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   558
                if (self.options.list_ignored
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   559
                    || self.matcher.exact_match(&filename))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   560
                    && self.dir_ignore(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   561
                {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   562
                    if self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   563
                        files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   564
                            .send((filename.to_owned(), Dispatch::Ignored))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   565
                            .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   566
                    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   567
                } else if self.options.list_unknown {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   568
                    files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   569
                        .send((filename.to_owned(), Dispatch::Unknown))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   570
                        .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   571
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   572
            } else if self.is_ignored(&filename) && self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   573
                files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   574
                    .send((filename.to_owned(), Dispatch::Ignored))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   575
                    .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   576
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   577
        } else if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   578
            // Used to be a file or a folder, now something else.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   579
            if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   580
                || self.matcher.matches(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   581
            {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   582
                files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   583
                    .send((filename.to_owned(), dispatch_missing(entry.state)))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   584
                    .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   585
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   586
        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   587
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   588
        Ok(())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   589
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   590
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   591
    /// A directory was found in the filesystem and needs to be traversed
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   592
    fn handle_traversed_dir<'b>(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   593
        &'a self,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   594
        scope: &rayon::Scope<'b>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   595
        files_sender: &'b crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   596
        old_results: &'a FastHashMap<Cow<HgPath>, Dispatch>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   597
        entry_option: Option<&'a DirstateEntry>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   598
        directory: HgPathBuf,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   599
        traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   600
    ) where
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   601
        'a: 'b,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   602
    {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   603
        scope.spawn(move |_| {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   604
            // Nested `if` until `rust-lang/rust#53668` is stable
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   605
            if let Some(entry) = entry_option {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   606
                // Used to be a file, is now a folder
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   607
                if self.matcher.matches_everything()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   608
                    || self.matcher.matches(&directory)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   609
                {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   610
                    files_sender
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   611
                        .send((
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   612
                            directory.to_owned(),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   613
                            dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   614
                        ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   615
                        .unwrap();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   616
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   617
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   618
            // Do we need to traverse it?
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   619
            if !self.is_ignored(&directory) || self.options.list_ignored {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   620
                self.traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   621
                    files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   622
                    directory,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   623
                    &old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   624
                    traversed_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   625
                )
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   626
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   627
        });
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   628
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   629
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   630
    /// Decides whether the directory needs to be listed, and if so handles the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   631
    /// entries in a separate thread.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   632
    fn traverse_dir(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   633
        &self,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   634
        files_sender: &crossbeam_channel::Sender<(HgPathBuf, Dispatch)>,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   635
        directory: impl AsRef<HgPath>,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   636
        old_results: &FastHashMap<Cow<HgPath>, Dispatch>,
46054
fd47483f1645 rust: use crossbeam-channel crate directly
Simon Sapin <simon-commits@exyr.org>
parents: 45862
diff changeset
   637
        traversed_sender: crossbeam_channel::Sender<HgPathBuf>,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   638
    ) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   639
        let directory = directory.as_ref();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   640
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   641
        if self.options.collect_traversed_dirs {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   642
            traversed_sender
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   643
                .send(directory.to_owned())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   644
                .expect("receiver should outlive sender");
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   645
        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   646
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   647
        let visit_entries = match self.matcher.visit_children_set(directory) {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   648
            VisitChildrenSet::Empty => return,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   649
            VisitChildrenSet::This | VisitChildrenSet::Recursive => None,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   650
            VisitChildrenSet::Set(set) => Some(set),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   651
        };
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   652
        let buf = match hg_path_to_path_buf(directory) {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   653
            Ok(b) => b,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   654
            Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   655
                files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   656
                    .send((directory.to_owned(), INVALID_PATH_DISPATCH))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   657
                    .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   658
                return;
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   659
            }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   660
        };
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   661
        let dir_path = self.root_dir.join(buf);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   662
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   663
        let skip_dot_hg = !directory.as_bytes().is_empty();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   664
        let entries = match list_directory(dir_path, skip_dot_hg) {
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   665
            Err(e) => {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   666
                files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   667
                    .send((directory.to_owned(), dispatch_os_error(&e)))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   668
                    .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   669
                return;
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   670
            }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   671
            Ok(entries) => entries,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   672
        };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   673
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   674
        rayon::scope(|scope| {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   675
            for (filename, dir_entry) in entries {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   676
                if let Some(ref set) = visit_entries {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   677
                    if !set.contains(filename.deref()) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   678
                        continue;
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   679
                    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   680
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   681
                // TODO normalize
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   682
                let filename = if directory.is_empty() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   683
                    filename.to_owned()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   684
                } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   685
                    directory.join(&filename)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   686
                };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   687
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   688
                if !old_results.contains_key(filename.deref()) {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   689
                    match self.handle_traversed_entry(
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   690
                        scope,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   691
                        files_sender,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   692
                        old_results,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   693
                        filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   694
                        dir_entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   695
                        traversed_sender.clone(),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   696
                    ) {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   697
                        Err(e) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   698
                            files_sender
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   699
                                .send((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   700
                                    directory.to_owned(),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   701
                                    dispatch_os_error(&e),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   702
                                ))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   703
                                .expect("receiver should outlive sender");
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   704
                        }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   705
                        Ok(_) => {}
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   706
                    }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   707
                }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   708
            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   709
        })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   710
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   711
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   712
    /// Add the files in the dirstate to the results.
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   713
    ///
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   714
    /// This takes a mutable reference to the results to account for the
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   715
    /// `extend` in timings
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   716
    #[cfg(feature = "dirstate-tree")]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   717
    #[timed]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   718
    pub fn extend_from_dmap(&self, results: &mut Vec<DispatchedPath<'a>>) {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   719
        results.par_extend(
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   720
            self.dmap
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   721
                .fs_iter(self.root_dir.clone())
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   722
                .par_bridge()
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   723
                .filter(|(path, _)| self.matcher.matches(path))
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   724
                .map(move |(filename, shortcut)| {
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   725
                    let entry = match shortcut {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   726
                        StatusShortcut::Entry(e) => e,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   727
                        StatusShortcut::Dispatch(d) => {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   728
                            return (Cow::Owned(filename), d)
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   729
                        }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   730
                    };
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   731
                    let filename_as_path = match hg_path_to_path_buf(&filename)
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   732
                    {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   733
                        Ok(f) => f,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   734
                        Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   735
                            return (
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   736
                                Cow::Owned(filename),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   737
                                INVALID_PATH_DISPATCH,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   738
                            )
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   739
                        }
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   740
                    };
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   741
                    let meta = self
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   742
                        .root_dir
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   743
                        .join(filename_as_path)
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   744
                        .symlink_metadata();
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   745
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   746
                    match meta {
45615
d5407b2e7689 rust: leverage improved match ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 45610
diff changeset
   747
                        Ok(m)
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   748
                            if !(m.file_type().is_file()
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   749
                                || m.file_type().is_symlink()) =>
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   750
                        {
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   751
                            (
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   752
                                Cow::Owned(filename),
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   753
                                dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   754
                            )
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   755
                        }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   756
                        Ok(m) => {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   757
                            let dispatch = dispatch_found(
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   758
                                &filename,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   759
                                entry,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   760
                                HgMetadata::from_metadata(m),
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   761
                                &self.dmap.copy_map,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   762
                                self.options,
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   763
                            );
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   764
                            (Cow::Owned(filename), dispatch)
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   765
                        }
45615
d5407b2e7689 rust: leverage improved match ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 45610
diff changeset
   766
                        Err(e)
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   767
                            if e.kind() == ErrorKind::NotFound
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   768
                                || e.raw_os_error() == Some(20) =>
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   769
                        {
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   770
                            // Rust does not yet have an `ErrorKind` for
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   771
                            // `NotADirectory` (errno 20)
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   772
                            // It happens if the dirstate contains `foo/bar`
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   773
                            // and foo is not a
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   774
                            // directory
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   775
                            (
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   776
                                Cow::Owned(filename),
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   777
                                dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   778
                            )
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   779
                        }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   780
                        Err(e) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   781
                            (Cow::Owned(filename), dispatch_os_error(&e))
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   782
                        }
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   783
                    }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   784
                }),
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   785
        );
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   786
    }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   787
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   788
    /// Add the files in the dirstate to the results.
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   789
    ///
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   790
    /// This takes a mutable reference to the results to account for the
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   791
    /// `extend` in timings
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   792
    #[cfg(not(feature = "dirstate-tree"))]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   793
    #[timed]
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   794
    pub fn extend_from_dmap(&self, results: &mut Vec<DispatchedPath<'a>>) {
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   795
        results.par_extend(
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   796
            self.dmap
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   797
                .par_iter()
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   798
                .filter(|(path, _)| self.matcher.matches(path))
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   799
                .map(move |(filename, entry)| {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   800
                    let filename: &HgPath = filename;
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   801
                    let filename_as_path = match hg_path_to_path_buf(filename)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   802
                    {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   803
                        Ok(f) => f,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   804
                        Err(_) => {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   805
                            return (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   806
                                Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   807
                                INVALID_PATH_DISPATCH,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   808
                            )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   809
                        }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   810
                    };
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   811
                    let meta = self
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   812
                        .root_dir
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   813
                        .join(filename_as_path)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   814
                        .symlink_metadata();
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   815
                    match meta {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   816
                        Ok(m)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   817
                            if !(m.file_type().is_file()
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   818
                                || m.file_type().is_symlink()) =>
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   819
                        {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   820
                            (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   821
                                Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   822
                                dispatch_missing(entry.state),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   823
                            )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   824
                        }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   825
                        Ok(m) => (
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   826
                            Cow::Borrowed(filename),
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   827
                            dispatch_found(
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   828
                                filename,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   829
                                *entry,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   830
                                HgMetadata::from_metadata(m),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   831
                                &self.dmap.copy_map,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   832
                                self.options,
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   833
                            ),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   834
                        ),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   835
                        Err(e)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   836
                            if e.kind() == ErrorKind::NotFound
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   837
                                || e.raw_os_error() == Some(20) =>
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   838
                        {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   839
                            // Rust does not yet have an `ErrorKind` for
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   840
                            // `NotADirectory` (errno 20)
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   841
                            // It happens if the dirstate contains `foo/bar`
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   842
                            // and foo is not a
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   843
                            // directory
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   844
                            (
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   845
                                Cow::Borrowed(filename),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   846
                                dispatch_missing(entry.state),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   847
                            )
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   848
                        }
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   849
                        Err(e) => {
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   850
                            (Cow::Borrowed(filename), dispatch_os_error(&e))
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   851
                        }
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   852
                    }
46489
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   853
                }),
fb6eca7b8c63 rust-status: honor matcher when using the dirstate-only fast-path (issue6483)
Raphaël Gomès <rgomes@octobus.net>
parents: 46054
diff changeset
   854
        );
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   855
    }
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   856
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   857
    /// Checks all files that are in the dirstate but were not found during the
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   858
    /// working directory traversal. This means that the rest must
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   859
    /// be either ignored, under a symlink or under a new nested repo.
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   860
    ///
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   861
    /// This takes a mutable reference to the results to account for the
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   862
    /// `extend` in timings
45610
496537c9c1b4 rust: start plugging the dirstate tree behind a feature gate
Raphaël Gomès <rgomes@octobus.net>
parents: 45358
diff changeset
   863
    #[cfg(not(feature = "dirstate-tree"))]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   864
    #[timed]
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   865
    pub fn handle_unknowns(&self, results: &mut Vec<DispatchedPath<'a>>) {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   866
        let to_visit: Vec<(&HgPath, &DirstateEntry)> =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   867
            if results.is_empty() && self.matcher.matches_everything() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   868
                self.dmap.iter().map(|(f, e)| (f.deref(), e)).collect()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   869
            } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   870
                // Only convert to a hashmap if needed.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   871
                let old_results: FastHashMap<_, _> =
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   872
                    results.iter().cloned().collect();
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   873
                self.dmap
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   874
                    .iter()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   875
                    .filter_map(move |(f, e)| {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   876
                        if !old_results.contains_key(f.deref())
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   877
                            && self.matcher.matches(f)
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   878
                        {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   879
                            Some((f.deref(), e))
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   880
                        } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   881
                            None
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   882
                        }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   883
                    })
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   884
                    .collect()
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   885
            };
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   886
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   887
        let path_auditor = PathAuditor::new(&self.root_dir);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   888
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   889
        let new_results = to_visit.into_par_iter().filter_map(
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   890
            |(filename, entry)| -> Option<_> {
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   891
                // Report ignored items in the dmap as long as they are not
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   892
                // under a symlink directory.
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   893
                if path_auditor.check(filename) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   894
                    // TODO normalize for case-insensitive filesystems
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   895
                    let buf = match hg_path_to_path_buf(filename) {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   896
                        Ok(x) => x,
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   897
                        Err(_) => {
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   898
                            return Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   899
                                Cow::Owned(filename.to_owned()),
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   900
                                INVALID_PATH_DISPATCH,
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   901
                            ));
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   902
                        }
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   903
                    };
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   904
                    Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   905
                        Cow::Owned(filename.to_owned()),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   906
                        match self.root_dir.join(&buf).symlink_metadata() {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   907
                            // File was just ignored, no links, and exists
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   908
                            Ok(meta) => {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   909
                                let metadata = HgMetadata::from_metadata(meta);
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   910
                                dispatch_found(
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   911
                                    filename,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   912
                                    *entry,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   913
                                    metadata,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   914
                                    &self.dmap.copy_map,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   915
                                    self.options,
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   916
                                )
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   917
                            }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   918
                            // File doesn't exist
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   919
                            Err(_) => dispatch_missing(entry.state),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   920
                        },
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   921
                    ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   922
                } else {
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   923
                    // It's either missing or under a symlink directory which
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   924
                    // we, in this case, report as missing.
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   925
                    Some((
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   926
                        Cow::Owned(filename.to_owned()),
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   927
                        dispatch_missing(entry.state),
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   928
                    ))
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   929
                }
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   930
            },
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   931
        );
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   932
45862
5c736ba5dc27 rust-status: don't bubble up os errors, translate them to bad matches
Raphaël Gomès <rgomes@octobus.net>
parents: 45615
diff changeset
   933
        results.par_extend(new_results);
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   934
    }
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   935
}
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   936
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
   937
#[timed]
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
   938
pub fn build_response<'a>(
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   939
    results: impl IntoIterator<Item = DispatchedPath<'a>>,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   940
    traversed: Vec<HgPathBuf>,
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   941
) -> (Vec<HgPathCow<'a>>, DirstateStatus<'a>) {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   942
    let mut lookup = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   943
    let mut modified = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   944
    let mut added = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   945
    let mut removed = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   946
    let mut deleted = vec![];
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   947
    let mut clean = vec![];
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   948
    let mut ignored = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   949
    let mut unknown = vec![];
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   950
    let mut bad = vec![];
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   951
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   952
    for (filename, dispatch) in results.into_iter() {
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   953
        match dispatch {
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   954
            Dispatch::Unknown => unknown.push(filename),
43602
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   955
            Dispatch::Unsure => lookup.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   956
            Dispatch::Modified => modified.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   957
            Dispatch::Added => added.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   958
            Dispatch::Removed => removed.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   959
            Dispatch::Deleted => deleted.push(filename),
889ac87e8bfd rust-status: improve status performance
Raphaël Gomès <rgomes@octobus.net>
parents: 43456
diff changeset
   960
            Dispatch::Clean => clean.push(filename),
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   961
            Dispatch::Ignored => ignored.push(filename),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   962
            Dispatch::None => {}
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   963
            Dispatch::Bad(reason) => bad.push((filename, reason)),
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   964
            Dispatch::Directory { .. } => {}
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   965
        }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   966
    }
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   967
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   968
    (
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   969
        lookup,
44525
f13d19549efd rust-status: rename `StatusResult` to `DirstateStatus`
Raphaël Gomès <rgomes@octobus.net>
parents: 44524
diff changeset
   970
        DirstateStatus {
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   971
            modified,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   972
            added,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   973
            removed,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   974
            deleted,
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   975
            clean,
44526
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   976
            ignored,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   977
            unknown,
61709b844420 rust-status: add missing variants to `Dispatch` enum
Raphaël Gomès <rgomes@octobus.net>
parents: 44525
diff changeset
   978
            bad,
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
   979
            traversed,
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   980
        },
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   981
    )
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   982
}
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   983
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   984
/// Get the status of files in the working directory.
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   985
///
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   986
/// This is the current entry-point for `hg-core` and is realistically unusable
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   987
/// outside of a Python context because its arguments need to provide a lot of
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   988
/// information that will not be necessary in the future.
44541
d880805d5442 hg-core: add function timing information
Raphaël Gomès <rgomes@octobus.net>
parents: 44539
diff changeset
   989
#[timed]
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   990
pub fn status<'a>(
43915
8c77826116f7 rust-dirstate-status: add `walk_explicit` implementation, use `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43818
diff changeset
   991
    dmap: &'a DirstateMap,
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   992
    matcher: &'a (impl Matcher + Sync),
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
   993
    root_dir: PathBuf,
44597
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44562
diff changeset
   994
    ignore_files: Vec<PathBuf>,
44524
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44523
diff changeset
   995
    options: StatusOptions,
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   996
) -> StatusResult<(
45112
470d306e616c rust-status: improve documentation and readability
Raphaël Gomès <rgomes@octobus.net>
parents: 45111
diff changeset
   997
    (Vec<HgPathCow<'a>>, DirstateStatus<'a>),
44528
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   998
    Vec<PatternFileWarning>,
c8891bca40fb rust-status: add bare `hg status` support in hg-core
Raphaël Gomès <rgomes@octobus.net>
parents: 44527
diff changeset
   999
)> {
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
  1000
    let (status, warnings) =
45111
7528699c6ccb rust-status: refactor status into a struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44973
diff changeset
  1001
        Status::new(dmap, matcher, root_dir, ignore_files, options)?;
44838
c802ec4f7196 rust-status: collect traversed directories if required
Raphaël Gomès <rgomes@octobus.net>
parents: 44837
diff changeset
  1002
45113
98817e5daca7 hg-core: define a `dirstate_status` `Operation`
Raphaël Gomès <rgomes@octobus.net>
parents: 45112
diff changeset
  1003
    Ok((status.run()?, warnings))
43271
99394e6c5d12 rust-dirstate-status: add first Rust implementation of `dirstate.status`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
  1004
}