1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Typed failures from [`crate::rev_list`].
use thiserror::Error;
/// Failure modes when walking revisions or parsing `rev-list` options.
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum RevListError {
/// Sparse filter blob bytes are not valid UTF-8 or not a blob object.
#[error("unable to parse sparse filter data in {object_id}")]
SparseFilterUnparsable {
/// Hex object id of the blob that was read.
object_id: String,
},
/// `sparse:oid=` spec did not resolve to a readable blob.
#[error("unable to access sparse blob in '{spec}'")]
SparseBlobUnreadable {
/// Original filter spec fragment.
spec: String,
},
/// A long option in `--stdin` mode requires a value on the following line.
#[error("option '{option}' requires a value")]
MissingOptionValue {
/// Option name without leading `--`.
option: String,
},
/// Unrecognized or malformed pseudo-option while reading `--stdin` revisions.
#[error("invalid option '{line}' in --stdin mode")]
InvalidStdinOption {
/// Raw stdin line.
line: String,
},
/// `--no-walk=` was given a value other than `sorted` or `unsorted`.
#[error("invalid argument to --no-walk")]
InvalidNoWalkArgument,
/// [`crate::revwalk::RevWalk::left_right_counts`] requires a single `A...B` token.
#[error("symmetric revision range (A...B) required for left/right commit counts")]
SymmetricRangeRequired,
/// [`crate::revwalk::RevWalk::walk`] got something other than one revision or range: an
/// option such as `--all`, the `--` separator, or several whitespace-separated tokens.
///
/// Use [`crate::revwalk::RevWalk::commits`] with
/// [`crate::revwalk::RevWalkListOptions::refs`] / [`crate::revwalk::RevWalkListOptions::paths`]
/// for ref selections, path limits, and multiple tokens.
#[error("'{spec}' is not a single revision or range; list several tokens, refs or paths with RevWalk::commits")]
UnsupportedWalkSpec {
/// The spec exactly as passed to `walk`.
spec: String,
},
/// [`crate::rev_list::rev_list`] got a raw `A...B` spec; symmetric ranges must be expanded
/// first with [`crate::revwalk::parse_rev_walk_tokens`] (positive tips, merge-base
/// exclusions, and the `symmetric_left` / `symmetric_right` options).
#[error(
"symmetric range '{spec}' must be expanded with parse_rev_walk_tokens before rev_list"
)]
UnexpandedSymmetricRange {
/// The unexpanded `A...B` spec.
spec: String,
},
/// Object walk expected a tree, blob, commit, or tag but read another kind from the ODB (upstream `t6102`).
#[error("object {input} is not a {expected}")]
UnexpectedObjectKind {
/// User-facing revision or path spec.
input: String,
/// Expected object type name (`tree`, `blob`, `commit`, `tag`).
expected: &'static str,
},
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::Error;
#[test]
fn variant_sparse_filter_unparsable() {
let err = Error::from(RevListError::SparseFilterUnparsable {
object_id: "abc".into(),
});
assert!(matches!(
err,
Error::RevList(RevListError::SparseFilterUnparsable { .. })
));
}
#[test]
fn variant_missing_option_value() {
let err = Error::from(RevListError::MissingOptionValue {
option: "glob".into(),
});
assert!(matches!(
err,
Error::RevList(RevListError::MissingOptionValue { .. })
));
}
#[test]
fn display_is_neutral() {
let msg = RevListError::InvalidNoWalkArgument.to_string();
assert!(!msg.contains("fatal:"));
assert!(!msg.contains("error:"));
}
#[test]
fn walk_spec_variants_keep_the_spec() {
let unsupported = RevListError::UnsupportedWalkSpec {
spec: "--all".into(),
};
assert!(unsupported.to_string().contains("'--all'"));
let symmetric = RevListError::UnexpandedSymmetricRange {
spec: "a...b".into(),
};
assert!(symmetric.to_string().contains("'a...b'"));
assert!(matches!(
Error::from(symmetric),
Error::RevList(RevListError::UnexpandedSymmetricRange { .. })
));
}
#[test]
fn unexpected_object_kind_display() {
let err = RevListError::UnexpectedObjectKind {
input: "abc".into(),
expected: "tree",
};
assert_eq!(err.to_string(), "object abc is not a tree");
}
}