rust/hg-core/src/dirstate/dirstate_tree/tree.rs
author Raphaël Gomès <rgomes@octobus.net>
Mon, 28 Sep 2020 11:16:12 +0200
changeset 45588 c35db907363d
parent 45562 b51167d70f5a
child 45709 91fafafd5a68
permissions -rw-r--r--
rust: format with rustfmt I suppose I ran the formatter on the tip but not on every patch. Differential Revision: https://phab.mercurial-scm.org/D9093
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     1
// tree.rs
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     2
//
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     3
// Copyright 2020, Raphaël Gomès <rgomes@octobus.net>
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     4
//
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     5
// This software may be used and distributed according to the terms of the
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     6
// GNU General Public License version 2 or any later version.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     7
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     8
use super::iter::Iter;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
     9
use super::node::{Directory, Node, NodeKind};
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    10
use crate::dirstate::dirstate_tree::iter::FsIter;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    11
use crate::dirstate::dirstate_tree::node::{InsertResult, RemoveResult};
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    12
use crate::utils::hg_path::{HgPath, HgPathBuf};
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    13
use crate::DirstateEntry;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    14
use std::path::PathBuf;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    15
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    16
/// A specialized tree to represent the Mercurial dirstate.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    17
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    18
/// # Advantages over a flat structure
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    19
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    20
/// The dirstate is inherently hierarchical, since it's a representation of the
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    21
/// file structure of the project. The current dirstate format is flat, and
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
/// while that affords us potentially great (unordered) iteration speeds, the
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    23
/// need to retrieve a given path is great enough that you need some kind of
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
/// hashmap or tree in a lot of cases anyway.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    26
/// Going with a tree allows us to be smarter:
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    27
///   - Skipping an ignored directory means we don't visit its entire subtree
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
///   - Security auditing does not need to reconstruct paths backwards to check
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
///     for symlinked directories, this can be done during the iteration in a
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    30
///     very efficient fashion
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    31
///   - We don't need to build the directory information in another struct,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    32
///     simplifying the code a lot, reducing the memory footprint and
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    33
///     potentially going faster depending on the implementation.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    34
///   - We can use it to store a (platform-dependent) caching mechanism [1]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    35
///   - And probably other types of optimizations.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    36
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
/// Only the first two items in this list are implemented as of this commit.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    38
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    39
/// [1]: https://www.mercurial-scm.org/wiki/DirsCachePlan
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    40
///       
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    41
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    42
/// # Structure
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    43
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    44
/// It's a prefix (radix) tree with no fixed arity, with a granularity of a
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    45
/// folder, allowing it to mimic a filesystem hierarchy:
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    46
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    47
/// ```text
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
/// foo/bar
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    49
/// foo/baz
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    50
/// test
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    51
/// ```
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    52
/// Will be represented (simplified) by:
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    53
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    54
/// ```text
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
/// Directory(root):
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
///   - File("test")
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
///   - Directory("foo"):
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    58
///     - File("bar")
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
///     - File("baz")
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
/// ```
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    61
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    62
/// Moreover, it is special-cased for storing the dirstate and as such handles
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    63
/// cases that a simple `HashMap` would handle, but while preserving the
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    64
/// hierarchy.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    65
/// For example:
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    66
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    67
/// ```shell
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    68
/// $ touch foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    69
/// $ hg add foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    70
/// $ hg commit -m "foo"
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    71
/// $ hg remove foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    72
/// $ rm foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    73
/// $ mkdir foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    74
/// $ touch foo/a
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    75
/// $ hg add foo/a
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    76
/// $ hg status
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    77
///   R foo
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    78
///   A foo/a
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    79
/// ```
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    80
/// To represent this in a tree, one needs to keep track of whether any given
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    81
/// file was a directory and whether any given directory was a file at the last
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    82
/// dirstate update. This tree stores that information, but only in the right
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    83
/// circumstances by respecting the high-level rules that prevent nonsensical
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    84
/// structures to exist:
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    85
///     - a file can only be added as a child of another file if the latter is
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
///       marked as `Removed`
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    87
///     - a file cannot replace a folder unless all its descendents are removed
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    88
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    89
/// This second rule is not checked by the tree for performance reasons, and
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    90
/// because high-level logic already prevents that state from happening.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    91
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    92
/// # Ordering
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    93
///
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    94
/// It makes no guarantee of ordering for now.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    95
#[derive(Debug, Default, Clone, PartialEq)]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    96
pub struct Tree {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    97
    pub root: Node,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    98
    files_count: usize,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    99
}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   100
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   101
impl Tree {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   102
    pub fn new() -> Self {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   103
        Self {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   104
            root: Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   105
                kind: NodeKind::Directory(Directory {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   106
                    was_file: None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   107
                    children: Default::default(),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   108
                }),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   109
            },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   110
            files_count: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   111
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   112
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   113
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   114
    /// How many files (not directories) are stored in the tree, including ones
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   115
    /// marked as `Removed`.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   116
    pub fn len(&self) -> usize {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   117
        self.files_count
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   118
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   119
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   120
    pub fn is_empty(&self) -> bool {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   121
        self.len() == 0
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   122
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   123
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   124
    /// Inserts a file in the tree and returns the previous entry if any.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   125
    pub fn insert(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   126
        &mut self,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   127
        path: impl AsRef<HgPath>,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   128
        kind: DirstateEntry,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   129
    ) -> Option<DirstateEntry> {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   130
        let old = self.insert_node(path, kind);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   131
        match old?.kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   132
            NodeKind::Directory(_) => None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   133
            NodeKind::File(f) => Some(f.entry),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   134
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   135
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   136
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   137
    /// Low-level insertion method that returns the previous node (directories
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   138
    /// included).
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   139
    fn insert_node(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   140
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   141
        path: impl AsRef<HgPath>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   142
        kind: DirstateEntry,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   143
    ) -> Option<Node> {
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   144
        let InsertResult {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   145
            did_insert,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   146
            old_entry,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   147
        } = self.root.insert(path.as_ref().as_bytes(), kind);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   148
        self.files_count += if did_insert { 1 } else { 0 };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   149
        old_entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   150
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   151
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   152
    /// Returns a reference to a node if it exists.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   153
    pub fn get_node(&self, path: impl AsRef<HgPath>) -> Option<&Node> {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   154
        self.root.get(path.as_ref().as_bytes())
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   155
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   156
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   157
    /// Returns a reference to the entry corresponding to `path` if it exists.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   158
    pub fn get(&self, path: impl AsRef<HgPath>) -> Option<&DirstateEntry> {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   159
        if let Some(node) = self.get_node(&path) {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   160
            return match &node.kind {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   161
                NodeKind::Directory(d) => {
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   162
                    d.was_file.as_ref().map(|f| &f.entry)
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   163
                }
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   164
                NodeKind::File(f) => Some(&f.entry),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   165
            };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   166
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   167
        None
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   168
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   169
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   170
    /// Returns `true` if an entry is found for the given `path`.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   171
    pub fn contains_key(&self, path: impl AsRef<HgPath>) -> bool {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   172
        self.get(path).is_some()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   173
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   174
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   175
    /// Returns a mutable reference to the entry corresponding to `path` if it
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   176
    /// exists.
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   177
    pub fn get_mut(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   178
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   179
        path: impl AsRef<HgPath>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   180
    ) -> Option<&mut DirstateEntry> {
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   181
        if let Some(kind) = self.root.get_mut(path.as_ref().as_bytes()) {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   182
            return match kind {
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   183
                NodeKind::Directory(d) => {
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   184
                    d.was_file.as_mut().map(|f| &mut f.entry)
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   185
                }
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   186
                NodeKind::File(f) => Some(&mut f.entry),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   187
            };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   188
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   189
        None
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   190
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   191
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   192
    /// Returns an iterator over the paths and corresponding entries in the
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   193
    /// tree.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   194
    pub fn iter(&self) -> Iter {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   195
        Iter::new(&self.root)
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   196
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   197
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   198
    /// Returns an iterator of all entries in the tree, with a special
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   199
    /// filesystem handling for the directories containing said entries. See
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   200
    /// the documentation of `FsIter` for more.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   201
    pub fn fs_iter(&self, root_dir: PathBuf) -> FsIter {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   202
        FsIter::new(&self.root, root_dir)
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   203
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   204
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   205
    /// Remove the entry at `path` and returns it, if it exists.
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   206
    pub fn remove(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   207
        &mut self,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   208
        path: impl AsRef<HgPath>,
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   209
    ) -> Option<DirstateEntry> {
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   210
        let RemoveResult { old_entry, .. } =
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   211
            self.root.remove(path.as_ref().as_bytes());
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   212
        self.files_count = self
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   213
            .files_count
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   214
            .checked_sub(if old_entry.is_some() { 1 } else { 0 })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   215
            .expect("removed too many files");
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   216
        old_entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   217
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   218
}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   219
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   220
impl<P: AsRef<HgPath>> Extend<(P, DirstateEntry)> for Tree {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   221
    fn extend<T: IntoIterator<Item = (P, DirstateEntry)>>(&mut self, iter: T) {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   222
        for (path, entry) in iter {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   223
            self.insert(path, entry);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   224
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   225
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   226
}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   227
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   228
impl<'a> IntoIterator for &'a Tree {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   229
    type Item = (HgPathBuf, DirstateEntry);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   230
    type IntoIter = Iter<'a>;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   231
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   232
    fn into_iter(self) -> Self::IntoIter {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   233
        self.iter()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   234
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   235
}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   236
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   237
#[cfg(test)]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   238
mod tests {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   239
    use super::*;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   240
    use crate::dirstate::dirstate_tree::node::File;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   241
    use crate::{EntryState, FastHashMap};
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   242
    use pretty_assertions::assert_eq;
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   243
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   244
    impl Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   245
        /// Shortcut for getting children of a node in tests.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   246
        fn children(&self) -> Option<&FastHashMap<Vec<u8>, Node>> {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   247
            match &self.kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   248
                NodeKind::Directory(d) => Some(&d.children),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   249
                NodeKind::File(_) => None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   250
            }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   251
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   252
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   253
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   254
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   255
    fn test_dirstate_tree() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   256
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   257
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   258
        assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   259
            tree.insert_node(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   260
                HgPath::new(b"we/p"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   261
                DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   262
                    state: EntryState::Normal,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   263
                    mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   264
                    mtime: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   265
                    size: 0
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   266
                }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   267
            ),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   268
            None
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   269
        );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   270
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   271
        assert!(tree.get_node(HgPath::new(b"we")).is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   272
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   273
            state: EntryState::Merged,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   274
            mode: 41,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   275
            mtime: 42,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   276
            size: 43,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   277
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   278
        assert_eq!(tree.insert_node(HgPath::new(b"foo/bar"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   279
        assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   280
            tree.get_node(HgPath::new(b"foo/bar")),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   281
            Some(&Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   282
                kind: NodeKind::File(File {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   283
                    was_directory: None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   284
                    entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   285
                })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   286
            })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   287
        );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   288
        // We didn't override the first entry we made
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   289
        assert!(tree.get_node(HgPath::new(b"we")).is_some(),);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   290
        // Inserting the same key again
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   291
        assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   292
            tree.insert_node(HgPath::new(b"foo/bar"), entry),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   293
            Some(Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   294
                kind: NodeKind::File(File {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   295
                    was_directory: None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   296
                    entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   297
                }),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   298
            })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   299
        );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   300
        // Inserting the two levels deep
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   301
        assert_eq!(tree.insert_node(HgPath::new(b"foo/bar/baz"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   302
        // Getting a file "inside a file" should return `None`
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   303
        assert_eq!(tree.get_node(HgPath::new(b"foo/bar/baz/bap"),), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   304
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   305
        assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   306
            tree.insert_node(HgPath::new(b"wasdir/subfile"), entry),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   307
            None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   308
        );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   309
        let removed_entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   310
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   311
            mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   312
            mtime: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   313
            size: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   314
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   315
        assert!(tree
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   316
            .insert_node(HgPath::new(b"wasdir"), removed_entry)
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   317
            .is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   318
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   319
        assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   320
            tree.get_node(HgPath::new(b"wasdir")),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   321
            Some(&Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   322
                kind: NodeKind::File(File {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   323
                    was_directory: Some(Box::new(Directory {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   324
                        was_file: None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   325
                        children: [(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   326
                            b"subfile".to_vec(),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   327
                            Node {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   328
                                kind: NodeKind::File(File {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   329
                                    was_directory: None,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   330
                                    entry,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   331
                                })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   332
                            }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   333
                        )]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   334
                        .to_vec()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   335
                        .into_iter()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   336
                        .collect()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   337
                    })),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   338
                    entry: removed_entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   339
                })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   340
            })
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   341
        );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   342
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   343
        assert!(tree.get(HgPath::new(b"wasdir/subfile")).is_some())
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   344
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   345
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   346
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   347
    fn test_insert_removed() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   348
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   349
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   350
            state: EntryState::Merged,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   351
            mode: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   352
            mtime: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   353
            size: 3,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   354
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   355
        let removed_entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   356
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   357
            mode: 10,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   358
            mtime: 20,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   359
            size: 30,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   360
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   361
        assert_eq!(tree.insert_node(HgPath::new(b"foo"), entry), None);
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   362
        assert_eq!(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   363
            tree.insert_node(HgPath::new(b"foo/a"), removed_entry),
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   364
            None
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   365
        );
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   366
        // The insert should not turn `foo` into a directory as `foo` is not
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   367
        // `Removed`.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   368
        match tree.get_node(HgPath::new(b"foo")).unwrap().kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   369
            NodeKind::Directory(_) => panic!("should be a file"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   370
            NodeKind::File(_) => {}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   371
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   372
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   373
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   374
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   375
            state: EntryState::Merged,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   376
            mode: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   377
            mtime: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   378
            size: 3,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   379
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   380
        let removed_entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   381
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   382
            mode: 10,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   383
            mtime: 20,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   384
            size: 30,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   385
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   386
        // The insert *should* turn `foo` into a directory as it is `Removed`.
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   387
        assert_eq!(tree.insert_node(HgPath::new(b"foo"), removed_entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   388
        assert_eq!(tree.insert_node(HgPath::new(b"foo/a"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   389
        match tree.get_node(HgPath::new(b"foo")).unwrap().kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   390
            NodeKind::Directory(_) => {}
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   391
            NodeKind::File(_) => panic!("should be a directory"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   392
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   393
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   394
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   395
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   396
    fn test_get() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   397
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   398
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   399
            state: EntryState::Merged,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   400
            mode: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   401
            mtime: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   402
            size: 3,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   403
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   404
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/c"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   405
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   406
        assert_eq!(tree.get(HgPath::new(b"a/b/c")), Some(&entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   407
        assert_eq!(tree.get(HgPath::new(b"a/b")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   408
        assert_eq!(tree.get(HgPath::new(b"a")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   409
        assert_eq!(tree.get(HgPath::new(b"a/b/c/d")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   410
        let entry2 = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   411
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   412
            mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   413
            mtime: 5,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   414
            size: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   415
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   416
        // was_directory
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   417
        assert_eq!(tree.insert(HgPath::new(b"a/b"), entry2), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   418
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   419
        assert_eq!(tree.get(HgPath::new(b"a/b")), Some(&entry2));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   420
        assert_eq!(tree.get(HgPath::new(b"a/b/c")), Some(&entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   421
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   422
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   423
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   424
        // was_file
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   425
        assert_eq!(tree.insert_node(HgPath::new(b"a"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   426
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   427
        assert_eq!(tree.insert_node(HgPath::new(b"a/b"), entry2), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   428
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   429
        assert_eq!(tree.get(HgPath::new(b"a/b")), Some(&entry2));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   430
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   431
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   432
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   433
    fn test_get_mut() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   434
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   435
        let mut entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   436
            state: EntryState::Merged,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   437
            mode: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   438
            mtime: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   439
            size: 3,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   440
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   441
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/c"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   442
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   443
        assert_eq!(tree.get_mut(HgPath::new(b"a/b/c")), Some(&mut entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   444
        assert_eq!(tree.get_mut(HgPath::new(b"a/b")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   445
        assert_eq!(tree.get_mut(HgPath::new(b"a")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   446
        assert_eq!(tree.get_mut(HgPath::new(b"a/b/c/d")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   447
        let mut entry2 = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   448
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   449
            mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   450
            mtime: 5,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   451
            size: 1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   452
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   453
        // was_directory
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   454
        assert_eq!(tree.insert(HgPath::new(b"a/b"), entry2), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   455
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   456
        assert_eq!(tree.get_mut(HgPath::new(b"a/b")), Some(&mut entry2));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   457
        assert_eq!(tree.get_mut(HgPath::new(b"a/b/c")), Some(&mut entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   458
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   459
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   460
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   461
        // was_file
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   462
        assert_eq!(tree.insert_node(HgPath::new(b"a"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   463
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   464
        assert_eq!(tree.insert_node(HgPath::new(b"a/b"), entry2), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   465
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   466
        assert_eq!(tree.get_mut(HgPath::new(b"a/b")), Some(&mut entry2));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   467
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   468
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   469
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   470
    fn test_remove() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   471
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   472
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   473
        assert_eq!(tree.remove(HgPath::new(b"foo")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   474
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   475
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   476
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   477
            state: EntryState::Normal,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   478
            mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   479
            mtime: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   480
            size: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   481
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   482
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/c"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   483
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   484
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   485
        assert_eq!(tree.remove(HgPath::new(b"a/b/c")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   486
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   487
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   488
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/x"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   489
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/y"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   490
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/z"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   491
        assert_eq!(tree.insert_node(HgPath::new(b"x"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   492
        assert_eq!(tree.insert_node(HgPath::new(b"y"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   493
        assert_eq!(tree.files_count, 5);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   494
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   495
        assert_eq!(tree.remove(HgPath::new(b"a/b/x")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   496
        assert_eq!(tree.files_count, 4);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   497
        assert_eq!(tree.remove(HgPath::new(b"a/b/x")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   498
        assert_eq!(tree.files_count, 4);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   499
        assert_eq!(tree.remove(HgPath::new(b"a/b/y")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   500
        assert_eq!(tree.files_count, 3);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   501
        assert_eq!(tree.remove(HgPath::new(b"a/b/z")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   502
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   503
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   504
        assert_eq!(tree.remove(HgPath::new(b"x")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   505
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   506
        assert_eq!(tree.remove(HgPath::new(b"y")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   507
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   508
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   509
        // `a` should have been cleaned up, no more files anywhere in its
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   510
        // descendents
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   511
        assert_eq!(tree.get_node(HgPath::new(b"a")), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   512
        assert_eq!(tree.root.children().unwrap().len(), 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   513
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   514
        let removed_entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   515
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   516
            ..entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   517
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   518
        assert_eq!(tree.insert(HgPath::new(b"a"), removed_entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   519
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/x"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   520
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   521
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   522
        assert_eq!(tree.remove(HgPath::new(b"a")), Some(removed_entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   523
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   524
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   525
        assert_eq!(tree.remove(HgPath::new(b"a/b/x")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   526
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   527
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   528
        // The entire tree should have been cleaned up, no more files anywhere
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   529
        // in its descendents
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   530
        assert_eq!(tree.root.children().unwrap().len(), 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   531
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   532
        let removed_entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   533
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   534
            ..entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   535
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   536
        assert_eq!(tree.insert(HgPath::new(b"a"), entry), None);
45588
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   537
        assert_eq!(
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   538
            tree.insert_node(HgPath::new(b"a/b/x"), removed_entry),
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   539
            None
c35db907363d rust: format with rustfmt
Raphaël Gomès <rgomes@octobus.net>
parents: 45562
diff changeset
   540
        );
45562
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   541
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   542
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   543
        assert_eq!(tree.remove(HgPath::new(b"a")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   544
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   545
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   546
        assert_eq!(tree.remove(HgPath::new(b"a/b/x")), Some(removed_entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   547
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   548
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   549
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   550
        // The entire tree should have been cleaned up, no more files anywhere
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   551
        // in its descendents
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   552
        assert_eq!(tree.root.children().unwrap().len(), 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   553
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   554
        assert_eq!(tree.insert(HgPath::new(b"d"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   555
        assert_eq!(tree.insert(HgPath::new(b"d/d/d"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   556
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   557
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   558
        // Deleting the nested file should not delete the top directory as it
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   559
        // used to be a file
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   560
        assert_eq!(tree.remove(HgPath::new(b"d/d/d")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   561
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   562
        assert!(tree.get_node(HgPath::new(b"d")).is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   563
        assert!(tree.remove(HgPath::new(b"d")).is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   564
        assert_eq!(tree.files_count, 0);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   565
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   566
        // Deleting the nested file should not delete the top file (other way
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   567
        // around from the last case)
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   568
        assert_eq!(tree.insert(HgPath::new(b"a/a"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   569
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   570
        assert_eq!(tree.insert(HgPath::new(b"a"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   571
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   572
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   573
        assert_eq!(tree.remove(HgPath::new(b"a/a")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   574
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   575
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   576
        assert!(tree.get_node(HgPath::new(b"a")).is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   577
        assert!(tree.get_node(HgPath::new(b"a/a")).is_none());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   578
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   579
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   580
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   581
    fn test_was_directory() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   582
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   583
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   584
        let entry = DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   585
            state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   586
            mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   587
            mtime: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   588
            size: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   589
        };
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   590
        assert_eq!(tree.insert_node(HgPath::new(b"a/b/c"), entry), None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   591
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   592
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   593
        assert!(tree.insert_node(HgPath::new(b"a"), entry).is_some());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   594
        let new_a = tree.root.children().unwrap().get(&b"a".to_vec()).unwrap();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   595
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   596
        match &new_a.kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   597
            NodeKind::Directory(_) => panic!(),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   598
            NodeKind::File(f) => {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   599
                let dir = f.was_directory.clone().unwrap();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   600
                let c = dir
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   601
                    .children
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   602
                    .get(&b"b".to_vec())
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   603
                    .unwrap()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   604
                    .children()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   605
                    .unwrap()
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   606
                    .get(&b"c".to_vec())
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   607
                    .unwrap();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   608
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   609
                assert_eq!(
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   610
                    match &c.kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   611
                        NodeKind::Directory(_) => panic!(),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   612
                        NodeKind::File(f) => f.entry,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   613
                    },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   614
                    entry
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   615
                );
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   616
            }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   617
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   618
        assert_eq!(tree.files_count, 2);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   619
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   620
        assert_eq!(tree.remove(HgPath::new(b"a/b/c")), Some(entry));
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   621
        assert_eq!(tree.files_count, 1);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   622
        dbg!(&tree);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   623
        let a = tree.get_node(HgPath::new(b"a")).unwrap();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   624
        match &a.kind {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   625
            NodeKind::Directory(_) => panic!(),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   626
            NodeKind::File(f) => {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   627
                // Directory in `was_directory` was emptied, should be removed
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   628
                assert_eq!(f.was_directory, None);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   629
            }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   630
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   631
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   632
    #[test]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   633
    fn test_extend() {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   634
        let insertions = [
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   635
            (
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   636
                HgPathBuf::from_bytes(b"d"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   637
                DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   638
                    state: EntryState::Added,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   639
                    mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   640
                    mtime: -1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   641
                    size: -1,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   642
                },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   643
            ),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   644
            (
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   645
                HgPathBuf::from_bytes(b"b"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   646
                DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   647
                    state: EntryState::Normal,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   648
                    mode: 33188,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   649
                    mtime: 1599647984,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   650
                    size: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   651
                },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   652
            ),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   653
            (
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   654
                HgPathBuf::from_bytes(b"a/a"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   655
                DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   656
                    state: EntryState::Normal,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   657
                    mode: 33188,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   658
                    mtime: 1599647984,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   659
                    size: 2,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   660
                },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   661
            ),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   662
            (
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   663
                HgPathBuf::from_bytes(b"d/d/d"),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   664
                DirstateEntry {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   665
                    state: EntryState::Removed,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   666
                    mode: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   667
                    mtime: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   668
                    size: 0,
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   669
                },
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   670
            ),
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   671
        ]
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   672
        .to_vec();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   673
        let mut tree = Tree::new();
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   674
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   675
        tree.extend(insertions.clone().into_iter());
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   676
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   677
        for (path, _) in &insertions {
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   678
            assert!(tree.contains_key(path), true);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   679
        }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   680
        assert_eq!(tree.files_count, 4);
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   681
    }
b51167d70f5a rust: add `dirstate_tree` module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   682
}