rust/rhg/src/commands/annotate.rs
author Mitchell Kember <mkember@janestreet.com>
Fri, 24 Jan 2025 12:01:12 -0500
changeset 52767 6183949219b2
child 52969 874c64e041b5
permissions -rw-r--r--
rhg: implement rhg annotate This initial implementation produces the same output as Python for all the files I've tried, and is usually 1.5-9x faster. The algorithm is mostly the same, but one key difference is that the Rust implementation only converts filelog revisions to changelog revisions if they will actually appear in the output. This does not support all the command line flags yet. In particular, --template, --include, --exclude, --skip, and whitespace-related flags will cause fallback to Python. Also, --rev 'wdir()' (often used by editor plugins) is not supported. There is also no pager.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52767
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     1
use core::str;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     2
use std::{collections::hash_map::Entry, ffi::OsString};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     3
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     4
use format_bytes::format_bytes;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     5
use hg::{
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     6
    encoding::Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     7
    operations::{
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     8
        annotate, AnnotateOptions, AnnotateOutput, ChangesetAnnotation,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
     9
    },
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    10
    revlog::changelog::Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    11
    FastHashMap, Revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    12
};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    13
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    14
use crate::{error::CommandError, utils::path_utils::resolve_file_args};
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    15
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    16
pub const HELP_TEXT: &str = "
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    17
show changeset information by line for each file
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    18
";
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    19
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    20
pub fn args() -> clap::Command {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    21
    clap::command!("annotate")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    22
        .alias("blame")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    23
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    24
            clap::Arg::new("files")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    25
                .help("files to annotate")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    26
                .required(true)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    27
                .num_args(1..)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    28
                .value_name("FILE")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    29
                .value_parser(clap::value_parser!(OsString)),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    30
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    31
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    32
            clap::Arg::new("rev")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    33
                .help("annotate the specified revision")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    34
                .short('r')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    35
                .long("rev")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    36
                .value_name("REV")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    37
                .default_value("."),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    38
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    39
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    40
            clap::Arg::new("no-follow")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    41
                .help("don't follow copies and renames")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    42
                .long("no-follow")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    43
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    44
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    45
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    46
            clap::Arg::new("text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    47
                .help("treat all files as text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    48
                .short('a')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    49
                .long("text")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    50
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    51
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    52
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    53
            clap::Arg::new("user")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    54
                .help("list the author (long with -v)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    55
                .short('u')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    56
                .long("user")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    57
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    58
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    59
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    60
            clap::Arg::new("number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    61
                .help("list the revision number (default)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    62
                .short('n')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    63
                .long("number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    64
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    65
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    66
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    67
            clap::Arg::new("changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    68
                .help("list the changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    69
                .short('c')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    70
                .long("changeset")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    71
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    72
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    73
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    74
            clap::Arg::new("date")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    75
                .help("list the date (short with -q)")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    76
                .short('d')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    77
                .long("date")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    78
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    79
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    80
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    81
            clap::Arg::new("file")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    82
                .help("list the filename")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    83
                .short('f')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    84
                .long("file")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    85
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    86
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    87
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    88
            clap::Arg::new("line-number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    89
                .help("show the line number at the first appearance")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    90
                .short('l')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    91
                .long("line-number")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    92
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    93
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    94
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    95
            clap::Arg::new("quiet")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    96
                .help("show short date for -d")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    97
                .short('q')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    98
                .long("quiet")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
    99
                .action(clap::ArgAction::SetTrue),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   100
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   101
        .arg(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   102
            clap::Arg::new("verbose")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   103
                .help("show full username for -u")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   104
                .short('v')
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   105
                .long("verbose")
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   106
                .action(clap::ArgAction::SetTrue)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   107
                .conflicts_with("quiet"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   108
        )
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   109
        .about(HELP_TEXT)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   110
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   111
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   112
pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   113
    let config = invocation.config;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   114
    if config.has_non_empty_section(b"annotate") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   115
        return Err(CommandError::unsupported(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   116
            "rhg annotate does not support any [annotate] configs",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   117
        ));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   118
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   119
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   120
    let repo = invocation.repo?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   121
    let args = invocation.subcommand_args;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   122
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   123
    let rev = args.get_one::<String>("rev").expect("rev has a default");
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   124
    let rev = hg::revset::resolve_single(rev, repo)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   125
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   126
    let files = match args.get_many::<OsString>("files") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   127
        None => vec![],
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   128
        Some(files) => resolve_file_args(repo, files)?,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   129
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   130
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   131
    let options = AnnotateOptions {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   132
        treat_binary_as_text: args.get_flag("text"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   133
        follow_copies: !args.get_flag("no-follow"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   134
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   135
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   136
    let mut include = Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   137
        user: args.get_flag("user"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   138
        number: args.get_flag("number"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   139
        changeset: args.get_flag("changeset"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   140
        date: args.get_flag("date"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   141
        file: args.get_flag("file"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   142
        line_number: args.get_flag("line-number"),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   143
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   144
    if !(include.user || include.file || include.date || include.changeset) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   145
        include.number = true;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   146
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   147
    if include.line_number && !(include.number || include.changeset) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   148
        return Err(CommandError::abort(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   149
            "at least one of -n/-c is required for -l",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   150
        ));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   151
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   152
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   153
    let verbosity = match (args.get_flag("quiet"), args.get_flag("verbose")) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   154
        (false, false) => Verbosity::Default,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   155
        (true, false) => Verbosity::Quiet,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   156
        (false, true) => Verbosity::Verbose,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   157
        (true, true) => unreachable!(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   158
    };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   159
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   160
    let changelog = repo.changelog()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   161
    let mut formatter = Formatter::new(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   162
        &changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   163
        invocation.ui.encoder(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   164
        include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   165
        verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   166
    );
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   167
    let mut stdout = invocation.ui.stdout_buffer();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   168
    for path in files {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   169
        match annotate(repo, &path, rev, options)? {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   170
            AnnotateOutput::Text(text) => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   171
                let annotations = formatter.format(text.annotations)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   172
                for (annotation, line) in annotations.iter().zip(&text.lines) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   173
                    stdout.write_all(&format_bytes!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   174
                        b"{}: {}", annotation, line
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   175
                    ))?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   176
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   177
                if let Some(line) = text.lines.last() {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   178
                    if !line.ends_with(b"\n") {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   179
                        stdout.write_all(b"\n")?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   180
                    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   181
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   182
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   183
            AnnotateOutput::Binary => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   184
                stdout.write_all(&format_bytes!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   185
                    b"{}: binary file\n",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   186
                    path.as_bytes()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   187
                ))?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   188
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   189
            AnnotateOutput::NotFound => {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   190
                let short = changelog.node_from_rev(rev).short();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   191
                return Err(CommandError::abort(format!(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   192
                    "{path}: no such file in rev {short:x}",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   193
                )));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   194
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   195
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   196
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   197
    stdout.flush()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   198
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   199
    Ok(())
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   200
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   201
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   202
struct Formatter<'a> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   203
    changelog: &'a Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   204
    encoder: &'a Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   205
    include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   206
    verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   207
    cache: FastHashMap<Revision, ChangesetData>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   208
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   209
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   210
#[derive(Copy, Clone)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   211
struct Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   212
    user: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   213
    number: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   214
    changeset: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   215
    date: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   216
    file: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   217
    line_number: bool,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   218
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   219
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   220
impl Include {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   221
    fn count(&self) -> usize {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   222
        // Rust guarantees false is 0 and true is 1.
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   223
        self.user as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   224
            + self.number as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   225
            + self.changeset as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   226
            + self.date as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   227
            + self.file as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   228
            + self.line_number as usize
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   229
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   230
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   231
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   232
#[derive(Copy, Clone)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   233
enum Verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   234
    Quiet,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   235
    Default,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   236
    Verbose,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   237
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   238
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   239
#[derive(Default)]
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   240
struct ChangesetData {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   241
    user: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   242
    changeset: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   243
    date: Option<Vec<u8>>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   244
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   245
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   246
impl ChangesetData {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   247
    fn create(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   248
        revision: Revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   249
        changelog: &Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   250
        include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   251
        verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   252
    ) -> Result<ChangesetData, CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   253
        let mut result = ChangesetData::default();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   254
        if !(include.user || include.changeset || include.date) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   255
            return Ok(result);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   256
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   257
        let entry = changelog.entry(revision)?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   258
        let data = entry.data()?;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   259
        if include.user {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   260
            let user = match verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   261
                Verbosity::Verbose => data.user(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   262
                _ => hg::utils::strings::short_user(data.user()),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   263
            };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   264
            result.user = Some(user.to_vec());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   265
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   266
        if include.changeset {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   267
            let changeset = entry.as_revlog_entry().node().short();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   268
            result.changeset = Some(format!("{:x}", changeset).into_bytes());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   269
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   270
        if include.date {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   271
            let date = data.timestamp()?.format(match verbosity {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   272
                Verbosity::Quiet => "%Y-%m-%d",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   273
                _ => "%a %b %d %H:%M:%S %Y %z",
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   274
            });
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   275
            result.date = Some(format!("{}", date).into_bytes());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   276
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   277
        Ok(result)
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   278
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   279
}
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   280
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   281
impl<'a> Formatter<'a> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   282
    fn new(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   283
        changelog: &'a Changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   284
        encoder: &'a Encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   285
        include: Include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   286
        verbosity: Verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   287
    ) -> Self {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   288
        let cache = FastHashMap::default();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   289
        Self {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   290
            changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   291
            encoder,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   292
            include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   293
            verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   294
            cache,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   295
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   296
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   297
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   298
    fn format(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   299
        &mut self,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   300
        annotations: Vec<ChangesetAnnotation>,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   301
    ) -> Result<Vec<Vec<u8>>, CommandError> {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   302
        let mut lines: Vec<Vec<Vec<u8>>> =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   303
            Vec::with_capacity(annotations.len());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   304
        let num_fields = self.include.count();
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   305
        let mut widths = vec![0usize; num_fields];
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   306
        for annotation in annotations {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   307
            let revision = annotation.revision;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   308
            let data = match self.cache.entry(revision) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   309
                Entry::Occupied(occupied) => occupied.into_mut(),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   310
                Entry::Vacant(vacant) => vacant.insert(ChangesetData::create(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   311
                    revision,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   312
                    self.changelog,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   313
                    self.include,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   314
                    self.verbosity,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   315
                )?),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   316
            };
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   317
            let mut fields = Vec::with_capacity(num_fields);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   318
            if let Some(user) = &data.user {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   319
                fields.push(user.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   320
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   321
            if self.include.number {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   322
                fields.push(format_bytes!(b"{}", revision));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   323
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   324
            if let Some(changeset) = &data.changeset {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   325
                fields.push(changeset.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   326
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   327
            if let Some(date) = &data.date {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   328
                fields.push(date.clone());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   329
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   330
            if self.include.file {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   331
                fields.push(annotation.path.into_vec());
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   332
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   333
            if self.include.line_number {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   334
                fields.push(format_bytes!(b"{}", annotation.line_number));
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   335
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   336
            for (field, width) in fields.iter().zip(widths.iter_mut()) {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   337
                *width = std::cmp::max(
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   338
                    *width,
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   339
                    self.encoder.column_width_bytes(field),
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   340
                );
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   341
            }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   342
            lines.push(fields);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   343
        }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   344
        let total_width = widths.iter().sum::<usize>() + num_fields - 1;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   345
        Ok(lines
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   346
            .iter()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   347
            .map(|fields| {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   348
                let mut bytes = Vec::with_capacity(total_width);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   349
                for (i, (field, width)) in
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   350
                    fields.iter().zip(widths.iter()).enumerate()
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   351
                {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   352
                    if i > 0 {
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   353
                        let colon =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   354
                            self.include.line_number && i == num_fields - 1;
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   355
                        bytes.push(if colon { b':' } else { b' ' });
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   356
                    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   357
                    let padding =
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   358
                        width - self.encoder.column_width_bytes(field);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   359
                    bytes.resize(bytes.len() + padding, b' ');
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   360
                    bytes.extend_from_slice(field);
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   361
                }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   362
                bytes
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   363
            })
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   364
            .collect())
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   365
    }
6183949219b2 rhg: implement rhg annotate
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
   366
}