rust/hg-core/src/matchers.rs
author Simon Sapin <simon.sapin@octobus.net>
Wed, 02 Jun 2021 18:03:43 +0200
changeset 47385 f6bb181c75f8
parent 47384 777c3d231913
child 47415 0ef8231e413f
permissions -rw-r--r--
rust: Parse "subinclude"d files along the way, not later When parsing a `.hgignore` file and encountering an `include:` line, the included file is parsed recursively right then in a depth-first fashion. With `subinclude:` however included files were parsed (recursively) much later. This changes it to be expanded during parsing, like `.hgignore`. The motivation for this is an upcoming changeset that needs to detect changes in which files are ignored or not. The plan is to hash all ignore files while they are being read, and store that hash in the dirstate (in v2 format). In order to allow a potential alternative implementations to read that format, the algorithm to compute that hash must be documented. Having a well-defined depth-first ordering for the tree of (sub-)included files makes that easier. Differential Revision: https://phab.mercurial-scm.org/D10834
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// matchers.rs
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2019 Raphaël Gomès <rgomes@octobus.net>
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
//! Structs and types for matching files and directories.
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
44529
52d40f8fb82d rust-matchers: add function to generate a regex matcher function
Raphaël Gomès <rgomes@octobus.net>
parents: 44387
diff changeset
    10
use crate::{
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    11
    dirstate::dirs_multiset::DirsChildrenMultiset,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    12
    filepatterns::{
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    13
        build_single_regex, filter_subincludes, get_patterns_from_file,
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
    14
        PatternFileWarning, PatternResult,
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    15
    },
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    16
    utils::{
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    17
        files::find_dirs,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    18
        hg_path::{HgPath, HgPathBuf},
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    19
        Escaped,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    20
    },
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    21
    DirsMultiset, DirstateMapError, FastHashMap, IgnorePattern, PatternError,
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
    22
    PatternSyntax,
44529
52d40f8fb82d rust-matchers: add function to generate a regex matcher function
Raphaël Gomès <rgomes@octobus.net>
parents: 44387
diff changeset
    23
};
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    24
44879
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
    25
use crate::filepatterns::normalize_path_bytes;
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
    26
use std::borrow::ToOwned;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
use std::collections::HashSet;
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
    28
use std::fmt::{Display, Error, Formatter};
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
    29
use std::iter::FromIterator;
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
    30
use std::ops::Deref;
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
    31
use std::path::{Path, PathBuf};
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
44861
83c97c0bd319 rust-matchers: add timing tracing to regex compilation
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
    33
use micro_timer::timed;
83c97c0bd319 rust-matchers: add timing tracing to regex compilation
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
    34
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
    35
#[derive(Debug, PartialEq)]
43850
1bb4e9b02984 rust-matchers: improve `Matcher` trait ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 43655
diff changeset
    36
pub enum VisitChildrenSet<'a> {
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
    /// Don't visit anything
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
    Empty,
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
    /// Only visit this directory
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
    This,
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
    /// Visit this directory and these subdirectories
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
    /// TODO Should we implement a `NonEmptyHashSet`?
43850
1bb4e9b02984 rust-matchers: improve `Matcher` trait ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 43655
diff changeset
    43
    Set(HashSet<&'a HgPath>),
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
    /// Visit this directory and all subdirectories
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
    Recursive,
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
}
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
pub trait Matcher {
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
    /// Explicitly listed files
43850
1bb4e9b02984 rust-matchers: improve `Matcher` trait ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 43655
diff changeset
    50
    fn file_set(&self) -> Option<&HashSet<&HgPath>>;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
    /// Returns whether `filename` is in `file_set`
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
    52
    fn exact_match(&self, filename: &HgPath) -> bool;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
    /// Returns whether `filename` is matched by this matcher
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
    54
    fn matches(&self, filename: &HgPath) -> bool;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
    /// Decides whether a directory should be visited based on whether it
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
    /// has potential matches in it or one of its subdirectories, and
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
    /// potentially lists which subdirectories of that directory should be
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
    /// visited. This is based on the match's primary, included, and excluded
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
    /// patterns.
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
    ///
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    61
    /// # Example
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
    ///
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
    /// Assume matchers `['path:foo/bar', 'rootfilesin:qux']`, we would
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    64
    /// return the following values (assuming the implementation of
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
    /// visit_children_set is capable of recognizing this; some implementations
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
    /// are not).
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    67
    ///
44009
72bced4f2936 rust-matchers: fixing cargo doc
Georges Racinet <georges.racinet@octobus.net>
parents: 43920
diff changeset
    68
    /// ```text
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
    /// ```ignore
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    70
    /// '' -> {'foo', 'qux'}
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
    /// 'baz' -> set()
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
    /// 'foo' -> {'bar'}
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    73
    /// // Ideally this would be `Recursive`, but since the prefix nature of
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    74
    /// // matchers is applied to the entire matcher, we have to downgrade this
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    75
    /// // to `This` due to the (yet to be implemented in Rust) non-prefix
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    76
    /// // `RootFilesIn'-kind matcher being mixed in.
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    77
    /// 'foo/bar' -> 'this'
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    78
    /// 'qux' -> 'this'
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
    /// ```
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
    /// # Important
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
    ///
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    82
    /// Most matchers do not know if they're representing files or
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    83
    /// directories. They see `['path:dir/f']` and don't know whether `f` is a
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    84
    /// file or a directory, so `visit_children_set('dir')` for most matchers
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
    /// will return `HashSet{ HgPath { "f" } }`, but if the matcher knows it's
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
    /// a file (like the yet to be implemented in Rust `ExactMatcher` does),
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    87
    /// it may return `VisitChildrenSet::This`.
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    88
    /// Do not rely on the return being a `HashSet` indicating that there are
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    89
    /// no files in this dir to investigate (or equivalently that if there are
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
    /// files to investigate in 'dir' that it will always return
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    91
    /// `VisitChildrenSet::This`).
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
    92
    fn visit_children_set(&self, directory: &HgPath) -> VisitChildrenSet;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
    /// Matcher will match everything and `files_set()` will be empty:
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
    /// optimization might be possible.
43655
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
    95
    fn matches_everything(&self) -> bool;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    96
    /// Matcher will match exactly the files in `files_set()`: optimization
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
    /// might be possible.
43655
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
    98
    fn is_exact(&self) -> bool;
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
}
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   100
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
/// Matches everything.
43852
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   102
///```
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   103
/// use hg::{ matchers::{Matcher, AlwaysMatcher}, utils::hg_path::HgPath };
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   104
///
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   105
/// let matcher = AlwaysMatcher;
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   106
///
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   107
/// assert_eq!(matcher.matches(HgPath::new(b"whatever")), true);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   108
/// assert_eq!(matcher.matches(HgPath::new(b"b.txt")), true);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   109
/// assert_eq!(matcher.matches(HgPath::new(b"main.c")), true);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   110
/// assert_eq!(matcher.matches(HgPath::new(br"re:.*\.c$")), true);
43852
542c8b277261 rust-matchers: add doctests for `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 43850
diff changeset
   111
/// ```
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   112
#[derive(Debug)]
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
pub struct AlwaysMatcher;
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
impl Matcher for AlwaysMatcher {
43850
1bb4e9b02984 rust-matchers: improve `Matcher` trait ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 43655
diff changeset
   116
    fn file_set(&self) -> Option<&HashSet<&HgPath>> {
1bb4e9b02984 rust-matchers: improve `Matcher` trait ergonomics
Raphaël Gomès <rgomes@octobus.net>
parents: 43655
diff changeset
   117
        None
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   119
    fn exact_match(&self, _filename: &HgPath) -> bool {
43655
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   120
        false
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   121
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   122
    fn matches(&self, _filename: &HgPath) -> bool {
43655
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   123
        true
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   124
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   125
    fn visit_children_set(&self, _directory: &HgPath) -> VisitChildrenSet {
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   126
        VisitChildrenSet::Recursive
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   127
    }
43655
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   128
    fn matches_everything(&self) -> bool {
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   129
        true
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   130
    }
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   131
    fn is_exact(&self) -> bool {
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   132
        false
27c25c0dc967 rust-matchers: remove default implementations for `Matcher` trait
Raphaël Gomès <rgomes@octobus.net>
parents: 43490
diff changeset
   133
    }
43490
a77d4fe347a4 rust-matchers: add `Matcher` trait and implement `AlwaysMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   134
}
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   135
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   136
/// Matches the input files exactly. They are interpreted as paths, not
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   137
/// patterns.
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   138
///
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   139
///```
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   140
/// use hg::{ matchers::{Matcher, FileMatcher}, utils::hg_path::{HgPath, HgPathBuf} };
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   141
///
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   142
/// let files = [HgPathBuf::from_bytes(b"a.txt"), HgPathBuf::from_bytes(br"re:.*\.c$")];
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   143
/// let matcher = FileMatcher::new(&files).unwrap();
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   144
///
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   145
/// assert_eq!(matcher.matches(HgPath::new(b"a.txt")), true);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   146
/// assert_eq!(matcher.matches(HgPath::new(b"b.txt")), false);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   147
/// assert_eq!(matcher.matches(HgPath::new(b"main.c")), false);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   148
/// assert_eq!(matcher.matches(HgPath::new(br"re:.*\.c$")), true);
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   149
/// ```
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   150
#[derive(Debug)]
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   151
pub struct FileMatcher<'a> {
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   152
    files: HashSet<&'a HgPath>,
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   153
    dirs: DirsMultiset,
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   154
}
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   155
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   156
impl<'a> FileMatcher<'a> {
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   157
    pub fn new(files: &'a [HgPathBuf]) -> Result<Self, DirstateMapError> {
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   158
        Ok(Self {
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   159
            files: HashSet::from_iter(files.iter().map(AsRef::as_ref)),
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   160
            dirs: DirsMultiset::from_manifest(files)?,
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   161
        })
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   162
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   163
    fn inner_matches(&self, filename: &HgPath) -> bool {
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   164
        self.files.contains(filename.as_ref())
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   165
    }
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   166
}
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   167
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   168
impl<'a> Matcher for FileMatcher<'a> {
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   169
    fn file_set(&self) -> Option<&HashSet<&HgPath>> {
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   170
        Some(&self.files)
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   171
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   172
    fn exact_match(&self, filename: &HgPath) -> bool {
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   173
        self.inner_matches(filename)
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   174
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   175
    fn matches(&self, filename: &HgPath) -> bool {
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   176
        self.inner_matches(filename)
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   177
    }
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   178
    fn visit_children_set(&self, directory: &HgPath) -> VisitChildrenSet {
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   179
        if self.files.is_empty() || !self.dirs.contains(&directory) {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   180
            return VisitChildrenSet::Empty;
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   181
        }
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   182
        let dirs_as_set = self.dirs.iter().map(Deref::deref).collect();
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   183
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   184
        let mut candidates: HashSet<&HgPath> =
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   185
            self.files.union(&dirs_as_set).cloned().collect();
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   186
        candidates.remove(HgPath::new(b""));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   187
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   188
        if !directory.as_ref().is_empty() {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   189
            let directory = [directory.as_ref().as_bytes(), b"/"].concat();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   190
            candidates = candidates
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   191
                .iter()
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   192
                .filter_map(|c| {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   193
                    if c.as_bytes().starts_with(&directory) {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   194
                        Some(HgPath::new(&c.as_bytes()[directory.len()..]))
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   195
                    } else {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   196
                        None
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   197
                    }
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   198
                })
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   199
                .collect();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   200
        }
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   201
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   202
        // `self.dirs` includes all of the directories, recursively, so if
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   203
        // we're attempting to match 'foo/bar/baz.txt', it'll have '', 'foo',
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   204
        // 'foo/bar' in it. Thus we can safely ignore a candidate that has a
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   205
        // '/' in it, indicating it's for a subdir-of-a-subdir; the immediate
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   206
        // subdir will be in there without a slash.
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   207
        VisitChildrenSet::Set(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   208
            candidates
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   209
                .iter()
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   210
                .filter_map(|c| {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   211
                    if c.bytes().all(|b| *b != b'/') {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   212
                        Some(*c)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   213
                    } else {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   214
                        None
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   215
                    }
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   216
                })
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   217
                .collect(),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   218
        )
43920
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   219
    }
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   220
    fn matches_everything(&self) -> bool {
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   221
        false
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   222
    }
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   223
    fn is_exact(&self) -> bool {
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   224
        true
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   225
    }
69c4f3cf2cdf rust-matchers: add `FileMatcher` implementation
Raphaël Gomès <rgomes@octobus.net>
parents: 43874
diff changeset
   226
}
44529
52d40f8fb82d rust-matchers: add function to generate a regex matcher function
Raphaël Gomès <rgomes@octobus.net>
parents: 44387
diff changeset
   227
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   228
/// Matches files that are included in the ignore rules.
44929
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   229
/// ```
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   230
/// use hg::{
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   231
///     matchers::{IncludeMatcher, Matcher},
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   232
///     IgnorePattern,
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   233
///     PatternSyntax,
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   234
///     utils::hg_path::HgPath
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   235
/// };
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   236
/// use std::path::Path;
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   237
/// ///
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   238
/// let ignore_patterns =
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   239
/// vec![IgnorePattern::new(PatternSyntax::RootGlob, b"this*", Path::new(""))];
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   240
/// let matcher = IncludeMatcher::new(ignore_patterns).unwrap();
44929
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   241
/// ///
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   242
/// assert_eq!(matcher.matches(HgPath::new(b"testing")), false);
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   243
/// assert_eq!(matcher.matches(HgPath::new(b"this should work")), true);
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   244
/// assert_eq!(matcher.matches(HgPath::new(b"this also")), true);
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   245
/// assert_eq!(matcher.matches(HgPath::new(b"but not this")), false);
9f96beb9bafe rust: remove support for `re2`
Raphaël Gomès <rgomes@octobus.net>
parents: 44911
diff changeset
   246
/// ```
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   247
pub struct IncludeMatcher<'a> {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   248
    patterns: Vec<u8>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   249
    match_fn: Box<dyn for<'r> Fn(&'r HgPath) -> bool + 'a + Sync>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   250
    /// Whether all the patterns match a prefix (i.e. recursively)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   251
    prefix: bool,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   252
    roots: HashSet<HgPathBuf>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   253
    dirs: HashSet<HgPathBuf>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   254
    parents: HashSet<HgPathBuf>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   255
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   256
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   257
impl<'a> Matcher for IncludeMatcher<'a> {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   258
    fn file_set(&self) -> Option<&HashSet<&HgPath>> {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   259
        None
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   260
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   261
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   262
    fn exact_match(&self, _filename: &HgPath) -> bool {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   263
        false
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   264
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   265
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   266
    fn matches(&self, filename: &HgPath) -> bool {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   267
        (self.match_fn)(filename.as_ref())
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   268
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   269
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   270
    fn visit_children_set(&self, directory: &HgPath) -> VisitChildrenSet {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   271
        let dir = directory.as_ref();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   272
        if self.prefix && self.roots.contains(dir) {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   273
            return VisitChildrenSet::Recursive;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   274
        }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   275
        if self.roots.contains(HgPath::new(b""))
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   276
            || self.roots.contains(dir)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   277
            || self.dirs.contains(dir)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   278
            || find_dirs(dir).any(|parent_dir| self.roots.contains(parent_dir))
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   279
        {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   280
            return VisitChildrenSet::This;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   281
        }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   282
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   283
        if self.parents.contains(directory.as_ref()) {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   284
            let multiset = self.get_all_parents_children();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   285
            if let Some(children) = multiset.get(dir) {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   286
                return VisitChildrenSet::Set(children.to_owned());
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   287
            }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   288
        }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   289
        VisitChildrenSet::Empty
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   290
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   291
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   292
    fn matches_everything(&self) -> bool {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   293
        false
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   294
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   295
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   296
    fn is_exact(&self) -> bool {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   297
        false
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   298
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   299
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   300
44601
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   301
/// Returns a function that matches an `HgPath` against the given regex
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   302
/// pattern.
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   303
///
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   304
/// This can fail when the pattern is invalid or not supported by the
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   305
/// underlying engine (the `regex` crate), for instance anything with
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   306
/// back-references.
44861
83c97c0bd319 rust-matchers: add timing tracing to regex compilation
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
   307
#[timed]
44601
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   308
fn re_matcher(
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   309
    pattern: &[u8],
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   310
) -> PatternResult<impl Fn(&HgPath) -> bool + Sync> {
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   311
    use std::io::Write;
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   312
44891
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44880
diff changeset
   313
    // The `regex` crate adds `.*` to the start and end of expressions if there
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44880
diff changeset
   314
    // are no anchors, so add the start anchor.
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44880
diff changeset
   315
    let mut escaped_bytes = vec![b'^', b'(', b'?', b':'];
44601
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   316
    for byte in pattern {
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   317
        if *byte > 127 {
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   318
            write!(escaped_bytes, "\\x{:x}", *byte).unwrap();
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   319
        } else {
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   320
            escaped_bytes.push(*byte);
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   321
        }
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   322
    }
44891
ad1ec40975aa rust-regex: fix issues with regex anchoring and performance
Raphaël Gomès <rgomes@octobus.net>
parents: 44880
diff changeset
   323
    escaped_bytes.push(b')');
44601
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   324
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   325
    // Avoid the cost of UTF8 checking
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   326
    //
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   327
    // # Safety
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   328
    // This is safe because we escaped all non-ASCII bytes.
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   329
    let pattern_string = unsafe { String::from_utf8_unchecked(escaped_bytes) };
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   330
    let re = regex::bytes::RegexBuilder::new(&pattern_string)
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   331
        .unicode(false)
44762
b15a37d85dbe rust-regex: increase the DFA size limit for the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
   332
        // Big repos with big `.hgignore` will hit the default limit and
b15a37d85dbe rust-regex: increase the DFA size limit for the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
   333
        // incur a significant performance hit. One repo's `hg status` hit
b15a37d85dbe rust-regex: increase the DFA size limit for the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
   334
        // multiple *minutes*.
b15a37d85dbe rust-regex: increase the DFA size limit for the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44604
diff changeset
   335
        .dfa_size_limit(50 * (1 << 20))
44601
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   336
        .build()
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   337
        .map_err(|e| PatternError::UnsupportedSyntax(e.to_string()))?;
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   338
496868f1030c rust-matchers: use the `regex` crate
Raphaël Gomès <rgomes@octobus.net>
parents: 44551
diff changeset
   339
    Ok(move |path: &HgPath| re.is_match(path.as_bytes()))
44529
52d40f8fb82d rust-matchers: add function to generate a regex matcher function
Raphaël Gomès <rgomes@octobus.net>
parents: 44387
diff changeset
   340
}
52d40f8fb82d rust-matchers: add function to generate a regex matcher function
Raphaël Gomès <rgomes@octobus.net>
parents: 44387
diff changeset
   341
44531
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   342
/// Returns the regex pattern and a function that matches an `HgPath` against
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   343
/// said regex formed by the given ignore patterns.
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   344
fn build_regex_match(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   345
    ignore_patterns: &[IgnorePattern],
44531
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   346
) -> PatternResult<(Vec<u8>, Box<dyn Fn(&HgPath) -> bool + Sync>)> {
44879
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   347
    let mut regexps = vec![];
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   348
    let mut exact_set = HashSet::new();
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   349
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   350
    for pattern in ignore_patterns {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   351
        if let Some(re) = build_single_regex(pattern)? {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   352
            regexps.push(re);
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   353
        } else {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   354
            let exact = normalize_path_bytes(&pattern.pattern);
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   355
            exact_set.insert(HgPathBuf::from_bytes(&exact));
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   356
        }
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   357
    }
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   358
44531
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   359
    let full_regex = regexps.join(&b'|');
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   360
44879
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   361
    // An empty pattern would cause the regex engine to incorrectly match the
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   362
    // (empty) root directory
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   363
    let func = if !(regexps.is_empty()) {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   364
        let matcher = re_matcher(&full_regex)?;
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   365
        let func = move |filename: &HgPath| {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   366
            exact_set.contains(filename) || matcher(filename)
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   367
        };
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   368
        Box::new(func) as Box<dyn Fn(&HgPath) -> bool + Sync>
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   369
    } else {
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   370
        let func = move |filename: &HgPath| exact_set.contains(filename);
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   371
        Box::new(func) as Box<dyn Fn(&HgPath) -> bool + Sync>
e0414fcd35e0 rust-filepatterns: match exact `rootglob`s with a `HashSet`, not in the regex
Raphaël Gomès <rgomes@octobus.net>
parents: 44861
diff changeset
   372
    };
44531
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   373
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   374
    Ok((full_regex, func))
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   375
}
a21881b40942 rust-matchers: add `build_regex_match` function
Raphaël Gomès <rgomes@octobus.net>
parents: 44530
diff changeset
   376
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   377
/// Returns roots and directories corresponding to each pattern.
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   378
///
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   379
/// This calculates the roots and directories exactly matching the patterns and
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   380
/// returns a tuple of (roots, dirs). It does not return other directories
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   381
/// which may also need to be considered, like the parent directories.
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   382
fn roots_and_dirs(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   383
    ignore_patterns: &[IgnorePattern],
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   384
) -> (Vec<HgPathBuf>, Vec<HgPathBuf>) {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   385
    let mut roots = Vec::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   386
    let mut dirs = Vec::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   387
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   388
    for ignore_pattern in ignore_patterns {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   389
        let IgnorePattern {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   390
            syntax, pattern, ..
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   391
        } = ignore_pattern;
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   392
        match syntax {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   393
            PatternSyntax::RootGlob | PatternSyntax::Glob => {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   394
                let mut root = vec![];
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   395
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   396
                for p in pattern.split(|c| *c == b'/') {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   397
                    if p.iter().any(|c| match *c {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   398
                        b'[' | b'{' | b'*' | b'?' => true,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   399
                        _ => false,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   400
                    }) {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   401
                        break;
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   402
                    }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   403
                    root.push(HgPathBuf::from_bytes(p));
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   404
                }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   405
                let buf =
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   406
                    root.iter().fold(HgPathBuf::new(), |acc, r| acc.join(r));
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   407
                roots.push(buf);
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   408
            }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   409
            PatternSyntax::Path | PatternSyntax::RelPath => {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   410
                let pat = HgPath::new(if pattern == b"." {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   411
                    &[] as &[u8]
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   412
                } else {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   413
                    pattern
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   414
                });
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   415
                roots.push(pat.to_owned());
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   416
            }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   417
            PatternSyntax::RootFiles => {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   418
                let pat = if pattern == b"." {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   419
                    &[] as &[u8]
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   420
                } else {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   421
                    pattern
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   422
                };
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   423
                dirs.push(HgPathBuf::from_bytes(pat));
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   424
            }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   425
            _ => {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   426
                roots.push(HgPathBuf::new());
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   427
            }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   428
        }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   429
    }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   430
    (roots, dirs)
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   431
}
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   432
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   433
/// Paths extracted from patterns
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   434
#[derive(Debug, PartialEq)]
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   435
struct RootsDirsAndParents {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   436
    /// Directories to match recursively
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   437
    pub roots: HashSet<HgPathBuf>,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   438
    /// Directories to match non-recursively
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   439
    pub dirs: HashSet<HgPathBuf>,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   440
    /// Implicitly required directories to go to items in either roots or dirs
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   441
    pub parents: HashSet<HgPathBuf>,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   442
}
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   443
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   444
/// Extract roots, dirs and parents from patterns.
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   445
fn roots_dirs_and_parents(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   446
    ignore_patterns: &[IgnorePattern],
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   447
) -> PatternResult<RootsDirsAndParents> {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   448
    let (roots, dirs) = roots_and_dirs(ignore_patterns);
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   449
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   450
    let mut parents = HashSet::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   451
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   452
    parents.extend(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   453
        DirsMultiset::from_manifest(&dirs)
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   454
            .map_err(|e| match e {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   455
                DirstateMapError::InvalidPath(e) => e,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   456
                _ => unreachable!(),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   457
            })?
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   458
            .iter()
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   459
            .map(ToOwned::to_owned),
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   460
    );
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   461
    parents.extend(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   462
        DirsMultiset::from_manifest(&roots)
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   463
            .map_err(|e| match e {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   464
                DirstateMapError::InvalidPath(e) => e,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   465
                _ => unreachable!(),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   466
            })?
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   467
            .iter()
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   468
            .map(ToOwned::to_owned),
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   469
    );
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   470
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   471
    Ok(RootsDirsAndParents {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   472
        roots: HashSet::from_iter(roots),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   473
        dirs: HashSet::from_iter(dirs),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   474
        parents,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   475
    })
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   476
}
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   477
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   478
/// Returns a function that checks whether a given file (in the general sense)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   479
/// should be matched.
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   480
fn build_match<'a, 'b>(
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   481
    ignore_patterns: Vec<IgnorePattern>,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   482
) -> PatternResult<(Vec<u8>, Box<dyn Fn(&HgPath) -> bool + 'b + Sync>)> {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   483
    let mut match_funcs: Vec<Box<dyn Fn(&HgPath) -> bool + Sync>> = vec![];
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   484
    // For debugging and printing
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   485
    let mut patterns = vec![];
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   486
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   487
    let (subincludes, ignore_patterns) = filter_subincludes(ignore_patterns)?;
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   488
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   489
    if !subincludes.is_empty() {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   490
        // Build prefix-based matcher functions for subincludes
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   491
        let mut submatchers = FastHashMap::default();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   492
        let mut prefixes = vec![];
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   493
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   494
        for sub_include in subincludes {
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   495
            let matcher = IncludeMatcher::new(sub_include.included_patterns)?;
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   496
            let match_fn =
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   497
                Box::new(move |path: &HgPath| matcher.matches(path));
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   498
            prefixes.push(sub_include.prefix.clone());
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   499
            submatchers.insert(sub_include.prefix.clone(), match_fn);
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   500
        }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   501
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   502
        let match_subinclude = move |filename: &HgPath| {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   503
            for prefix in prefixes.iter() {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   504
                if let Some(rel) = filename.relative_to(prefix) {
44998
26114bd6ec60 rust: do a clippy pass
Raphaël Gomès <rgomes@octobus.net>
parents: 44929
diff changeset
   505
                    if (submatchers[prefix])(rel) {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   506
                        return true;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   507
                    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   508
                }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   509
            }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   510
            false
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   511
        };
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   512
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   513
        match_funcs.push(Box::new(match_subinclude));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   514
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   515
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   516
    if !ignore_patterns.is_empty() {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   517
        // Either do dumb matching if all patterns are rootfiles, or match
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   518
        // with a regex.
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   519
        if ignore_patterns
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   520
            .iter()
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   521
            .all(|k| k.syntax == PatternSyntax::RootFiles)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   522
        {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   523
            let dirs: HashSet<_> = ignore_patterns
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   524
                .iter()
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   525
                .map(|k| k.pattern.to_owned())
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   526
                .collect();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   527
            let mut dirs_vec: Vec<_> = dirs.iter().cloned().collect();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   528
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   529
            let match_func = move |path: &HgPath| -> bool {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   530
                let path = path.as_bytes();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   531
                let i = path.iter().rfind(|a| **a == b'/');
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   532
                let dir = if let Some(i) = i {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   533
                    &path[..*i as usize]
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   534
                } else {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   535
                    b"."
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   536
                };
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   537
                dirs.contains(dir.deref())
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   538
            };
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   539
            match_funcs.push(Box::new(match_func));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   540
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   541
            patterns.extend(b"rootfilesin: ");
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   542
            dirs_vec.sort();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   543
            patterns.extend(dirs_vec.escaped_bytes());
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   544
        } else {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   545
            let (new_re, match_func) = build_regex_match(&ignore_patterns)?;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   546
            patterns = new_re;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   547
            match_funcs.push(match_func)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   548
        }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   549
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   550
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   551
    Ok(if match_funcs.len() == 1 {
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   552
        (patterns, match_funcs.remove(0))
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   553
    } else {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   554
        (
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   555
            patterns,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   556
            Box::new(move |f: &HgPath| -> bool {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   557
                match_funcs.iter().any(|match_func| match_func(f))
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   558
            }),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   559
        )
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   560
    })
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   561
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   562
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   563
/// Parses all "ignore" files with their recursive includes and returns a
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   564
/// function that checks whether a given file (in the general sense) should be
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   565
/// ignored.
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   566
pub fn get_ignore_function<'a>(
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   567
    all_pattern_files: Vec<PathBuf>,
47384
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
   568
    root_dir: &Path,
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   569
) -> PatternResult<(
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   570
    Box<dyn for<'r> Fn(&'r HgPath) -> bool + Sync + 'a>,
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   571
    Vec<PatternFileWarning>,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   572
)> {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   573
    let mut all_patterns = vec![];
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   574
    let mut all_warnings = vec![];
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   575
47384
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
   576
    for pattern_file in &all_pattern_files {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   577
        let (patterns, warnings) =
47384
777c3d231913 rust: Make some file path parameters less generic
Simon Sapin <simon.sapin@octobus.net>
parents: 45610
diff changeset
   578
            get_patterns_from_file(pattern_file, root_dir)?;
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   579
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   580
        all_patterns.extend(patterns.to_owned());
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   581
        all_warnings.extend(warnings);
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   582
    }
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   583
    let matcher = IncludeMatcher::new(all_patterns)?;
44604
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   584
    Ok((
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   585
        Box::new(move |path: &HgPath| matcher.matches(path)),
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   586
        all_warnings,
e62052d0f377 rust-status: only involve ignore mechanism when needed
Raphaël Gomès <rgomes@octobus.net>
parents: 44601
diff changeset
   587
    ))
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   588
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   589
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   590
impl<'a> IncludeMatcher<'a> {
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   591
    pub fn new(ignore_patterns: Vec<IgnorePattern>) -> PatternResult<Self> {
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   592
        let RootsDirsAndParents {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   593
            roots,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   594
            dirs,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   595
            parents,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   596
        } = roots_dirs_and_parents(&ignore_patterns)?;
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   597
        let prefix = ignore_patterns.iter().any(|k| match k.syntax {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   598
            PatternSyntax::Path | PatternSyntax::RelPath => true,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   599
            _ => false,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   600
        });
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   601
        let (patterns, match_fn) = build_match(ignore_patterns)?;
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   602
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   603
        Ok(Self {
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   604
            patterns,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   605
            match_fn,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   606
            prefix,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   607
            roots,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   608
            dirs,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   609
            parents,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   610
        })
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   611
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   612
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   613
    fn get_all_parents_children(&self) -> DirsChildrenMultiset {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   614
        // TODO cache
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   615
        let thing = self
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   616
            .dirs
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   617
            .iter()
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   618
            .chain(self.roots.iter())
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   619
            .chain(self.parents.iter());
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   620
        DirsChildrenMultiset::new(thing, Some(&self.parents))
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   621
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   622
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   623
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   624
impl<'a> Display for IncludeMatcher<'a> {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   625
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
44880
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   626
        // XXX What about exact matches?
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   627
        // I'm not sure it's worth it to clone the HashSet and keep it
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   628
        // around just in case someone wants to display the matcher, plus
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   629
        // it's going to be unreadable after a few entries, but we need to
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   630
        // inform in this display that exact matches are being used and are
de0fb4463a3d rust-matchers: add TODO about incomplete `Display` for `IncludeMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44879
diff changeset
   631
        // (on purpose) missing from the `includes`.
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   632
        write!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   633
            f,
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   634
            "IncludeMatcher(includes='{}')",
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   635
            String::from_utf8_lossy(&self.patterns.escaped_bytes())
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   636
        )
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   637
    }
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   638
}
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   639
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   640
#[cfg(test)]
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   641
mod tests {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   642
    use super::*;
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   643
    use pretty_assertions::assert_eq;
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   644
    use std::path::Path;
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   645
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   646
    #[test]
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   647
    fn test_roots_and_dirs() {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   648
        let pats = vec![
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   649
            IgnorePattern::new(PatternSyntax::Glob, b"g/h/*", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   650
            IgnorePattern::new(PatternSyntax::Glob, b"g/h", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   651
            IgnorePattern::new(PatternSyntax::Glob, b"g*", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   652
        ];
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   653
        let (roots, dirs) = roots_and_dirs(&pats);
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   654
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   655
        assert_eq!(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   656
            roots,
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   657
            vec!(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   658
                HgPathBuf::from_bytes(b"g/h"),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   659
                HgPathBuf::from_bytes(b"g/h"),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   660
                HgPathBuf::new()
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   661
            ),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   662
        );
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   663
        assert_eq!(dirs, vec!());
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   664
    }
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   665
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   666
    #[test]
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   667
    fn test_roots_dirs_and_parents() {
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   668
        let pats = vec![
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   669
            IgnorePattern::new(PatternSyntax::Glob, b"g/h/*", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   670
            IgnorePattern::new(PatternSyntax::Glob, b"g/h", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   671
            IgnorePattern::new(PatternSyntax::Glob, b"g*", Path::new("")),
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   672
        ];
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   673
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   674
        let mut roots = HashSet::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   675
        roots.insert(HgPathBuf::from_bytes(b"g/h"));
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   676
        roots.insert(HgPathBuf::new());
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   677
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   678
        let dirs = HashSet::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   679
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   680
        let mut parents = HashSet::new();
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   681
        parents.insert(HgPathBuf::new());
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   682
        parents.insert(HgPathBuf::from_bytes(b"g"));
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   683
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   684
        assert_eq!(
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   685
            roots_dirs_and_parents(&pats).unwrap(),
44534
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44532
diff changeset
   686
            RootsDirsAndParents {
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44532
diff changeset
   687
                roots,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44532
diff changeset
   688
                dirs,
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44532
diff changeset
   689
                parents
483fce658e43 rust-status: refactor options into a `StatusOptions` struct
Raphaël Gomès <rgomes@octobus.net>
parents: 44532
diff changeset
   690
            }
44530
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   691
        );
d4e8cfcde012 rust-matchers: add functions to get roots, dirs and parents from patterns
Raphaël Gomès <rgomes@octobus.net>
parents: 44529
diff changeset
   692
    }
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   693
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   694
    #[test]
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   695
    fn test_filematcher_visit_children_set() {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   696
        // Visitchildrenset
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   697
        let files = vec![HgPathBuf::from_bytes(b"dir/subdir/foo.txt")];
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   698
        let matcher = FileMatcher::new(&files).unwrap();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   699
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   700
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   701
        set.insert(HgPath::new(b"dir"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   702
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   703
            matcher.visit_children_set(HgPath::new(b"")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   704
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   705
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   706
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   707
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   708
        set.insert(HgPath::new(b"subdir"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   709
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   710
            matcher.visit_children_set(HgPath::new(b"dir")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   711
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   712
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   713
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   714
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   715
        set.insert(HgPath::new(b"foo.txt"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   716
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   717
            matcher.visit_children_set(HgPath::new(b"dir/subdir")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   718
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   719
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   720
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   721
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   722
            matcher.visit_children_set(HgPath::new(b"dir/subdir/x")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   723
            VisitChildrenSet::Empty
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   724
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   725
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   726
            matcher.visit_children_set(HgPath::new(b"dir/subdir/foo.txt")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   727
            VisitChildrenSet::Empty
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   728
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   729
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   730
            matcher.visit_children_set(HgPath::new(b"folder")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   731
            VisitChildrenSet::Empty
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   732
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   733
    }
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   734
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   735
    #[test]
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   736
    fn test_filematcher_visit_children_set_files_and_dirs() {
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   737
        let files = vec![
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   738
            HgPathBuf::from_bytes(b"rootfile.txt"),
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   739
            HgPathBuf::from_bytes(b"a/file1.txt"),
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   740
            HgPathBuf::from_bytes(b"a/b/file2.txt"),
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   741
            // No file in a/b/c
45610
75f785888a7b rust-matchers: make `Matcher` trait object-safe
Raphaël Gomès <rgomes@octobus.net>
parents: 44998
diff changeset
   742
            HgPathBuf::from_bytes(b"a/b/c/d/file4.txt"),
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   743
        ];
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   744
        let matcher = FileMatcher::new(&files).unwrap();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   745
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   746
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   747
        set.insert(HgPath::new(b"a"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   748
        set.insert(HgPath::new(b"rootfile.txt"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   749
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   750
            matcher.visit_children_set(HgPath::new(b"")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   751
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   752
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   753
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   754
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   755
        set.insert(HgPath::new(b"b"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   756
        set.insert(HgPath::new(b"file1.txt"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   757
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   758
            matcher.visit_children_set(HgPath::new(b"a")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   759
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   760
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   761
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   762
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   763
        set.insert(HgPath::new(b"c"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   764
        set.insert(HgPath::new(b"file2.txt"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   765
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   766
            matcher.visit_children_set(HgPath::new(b"a/b")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   767
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   768
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   769
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   770
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   771
        set.insert(HgPath::new(b"d"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   772
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   773
            matcher.visit_children_set(HgPath::new(b"a/b/c")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   774
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   775
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   776
        let mut set = HashSet::new();
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   777
        set.insert(HgPath::new(b"file4.txt"));
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   778
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   779
            matcher.visit_children_set(HgPath::new(b"a/b/c/d")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   780
            VisitChildrenSet::Set(set)
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   781
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   782
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   783
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   784
            matcher.visit_children_set(HgPath::new(b"a/b/c/d/e")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   785
            VisitChildrenSet::Empty
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   786
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   787
        assert_eq!(
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   788
            matcher.visit_children_set(HgPath::new(b"folder")),
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   789
            VisitChildrenSet::Empty
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   790
        );
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   791
    }
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   792
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   793
    #[test]
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   794
    fn test_includematcher() {
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   795
        // VisitchildrensetPrefix
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   796
        let matcher = IncludeMatcher::new(vec![IgnorePattern::new(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   797
            PatternSyntax::RelPath,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   798
            b"dir/subdir",
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   799
            Path::new(""),
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   800
        )])
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   801
        .unwrap();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   802
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   803
        let mut set = HashSet::new();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   804
        set.insert(HgPath::new(b"dir"));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   805
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   806
            matcher.visit_children_set(HgPath::new(b"")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   807
            VisitChildrenSet::Set(set)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   808
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   809
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   810
        let mut set = HashSet::new();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   811
        set.insert(HgPath::new(b"subdir"));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   812
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   813
            matcher.visit_children_set(HgPath::new(b"dir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   814
            VisitChildrenSet::Set(set)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   815
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   816
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   817
            matcher.visit_children_set(HgPath::new(b"dir/subdir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   818
            VisitChildrenSet::Recursive
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   819
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   820
        // OPT: This should probably be 'all' if its parent is?
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   821
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   822
            matcher.visit_children_set(HgPath::new(b"dir/subdir/x")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   823
            VisitChildrenSet::This
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   824
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   825
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   826
            matcher.visit_children_set(HgPath::new(b"folder")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   827
            VisitChildrenSet::Empty
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   828
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   829
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   830
        // VisitchildrensetRootfilesin
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   831
        let matcher = IncludeMatcher::new(vec![IgnorePattern::new(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   832
            PatternSyntax::RootFiles,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   833
            b"dir/subdir",
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   834
            Path::new(""),
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   835
        )])
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   836
        .unwrap();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   837
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   838
        let mut set = HashSet::new();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   839
        set.insert(HgPath::new(b"dir"));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   840
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   841
            matcher.visit_children_set(HgPath::new(b"")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   842
            VisitChildrenSet::Set(set)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   843
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   844
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   845
        let mut set = HashSet::new();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   846
        set.insert(HgPath::new(b"subdir"));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   847
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   848
            matcher.visit_children_set(HgPath::new(b"dir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   849
            VisitChildrenSet::Set(set)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   850
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   851
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   852
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   853
            matcher.visit_children_set(HgPath::new(b"dir/subdir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   854
            VisitChildrenSet::This
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   855
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   856
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   857
            matcher.visit_children_set(HgPath::new(b"dir/subdir/x")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   858
            VisitChildrenSet::Empty
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   859
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   860
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   861
            matcher.visit_children_set(HgPath::new(b"folder")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   862
            VisitChildrenSet::Empty
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   863
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   864
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   865
        // VisitchildrensetGlob
47385
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   866
        let matcher = IncludeMatcher::new(vec![IgnorePattern::new(
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   867
            PatternSyntax::Glob,
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   868
            b"dir/z*",
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   869
            Path::new(""),
f6bb181c75f8 rust: Parse "subinclude"d files along the way, not later
Simon Sapin <simon.sapin@octobus.net>
parents: 47384
diff changeset
   870
        )])
44532
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   871
        .unwrap();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   872
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   873
        let mut set = HashSet::new();
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   874
        set.insert(HgPath::new(b"dir"));
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   875
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   876
            matcher.visit_children_set(HgPath::new(b"")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   877
            VisitChildrenSet::Set(set)
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   878
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   879
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   880
            matcher.visit_children_set(HgPath::new(b"folder")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   881
            VisitChildrenSet::Empty
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   882
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   883
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   884
            matcher.visit_children_set(HgPath::new(b"dir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   885
            VisitChildrenSet::This
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   886
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   887
        // OPT: these should probably be set().
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   888
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   889
            matcher.visit_children_set(HgPath::new(b"dir/subdir")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   890
            VisitChildrenSet::This
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   891
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   892
        assert_eq!(
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   893
            matcher.visit_children_set(HgPath::new(b"dir/subdir/x")),
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   894
            VisitChildrenSet::This
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   895
        );
c697638e0e91 rust-matchers: add `IgnoreMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44531
diff changeset
   896
    }
44387
54d185eb24b5 rust-matchers: implement `visit_children_set` for `FileMatcher`
Raphaël Gomès <rgomes@octobus.net>
parents: 44009
diff changeset
   897
}