Skip to content

Commit d7f7788

Browse files
committed
Detect rebase state
1 parent 1db20cb commit d7f7788

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

src/todo_file.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod errors;
99
mod history;
1010
mod line;
1111
mod line_parser;
12+
mod state;
1213
mod todo_file_options;
1314
mod utils;
1415

@@ -19,6 +20,7 @@ use std::{
1920
slice::Iter,
2021
};
2122

23+
use state::detect_state;
2224
use version_track::Version;
2325

2426
pub(crate) use self::{
@@ -27,6 +29,7 @@ pub(crate) use self::{
2729
errors::ParseError,
2830
line::Line,
2931
line_parser::LineParser,
32+
state::State,
3033
todo_file_options::TodoFileOptions,
3134
};
3235
use self::{
@@ -48,6 +51,7 @@ pub(crate) struct TodoFile {
4851
options: TodoFileOptions,
4952
selected_line_index: usize,
5053
version: Version,
54+
state: State,
5155
}
5256

5357
impl TodoFile {
@@ -64,6 +68,7 @@ impl TodoFile {
6468
options,
6569
selected_line_index: 0,
6670
version: Version::new(),
71+
state: State::Initial,
6772
}
6873
}
6974

@@ -112,6 +117,7 @@ impl TodoFile {
112117
})
113118
.collect();
114119
self.set_lines(lines?);
120+
self.state = detect_state(&self.filepath)?;
115121
Ok(())
116122
}
117123

@@ -321,6 +327,13 @@ impl TodoFile {
321327
&self.version
322328
}
323329

330+
/// Get the current state
331+
#[must_use]
332+
#[inline]
333+
pub const fn state(&self) -> &State {
334+
&self.state
335+
}
336+
324337
/// Get the selected line.
325338
#[must_use]
326339
pub(crate) fn get_selected_line(&self) -> Option<&Line> {

src/todo_file/errors/io.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ pub(crate) enum FileReadErrorCause {
1515
/// Caused by a parse error
1616
#[error(transparent)]
1717
ParseError(#[from] ParseError),
18+
/// Caused by the file path returning None for parent()
19+
#[error("NoParentDir")]
20+
NoParentDir(),
1821
}
1922

2023
impl PartialEq for FileReadErrorCause {
@@ -23,6 +26,7 @@ impl PartialEq for FileReadErrorCause {
2326
match (self, other) {
2427
(Self::IoError(self_err), Self::IoError(other_err)) => self_err.kind() == other_err.kind(),
2528
(Self::ParseError(self_err), Self::ParseError(other_err)) => self_err == other_err,
29+
(Self::NoParentDir(), Self::NoParentDir()) => true,
2630
_ => false,
2731
}
2832
}

src/todo_file/state.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::{
2+
fmt::{Display, Formatter},
3+
path::{Path, PathBuf},
4+
};
5+
6+
use crate::todo_file::{FileReadErrorCause, IoError};
7+
8+
/// Describes the state of rebase when editing the rebase todo file.
9+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10+
#[allow(clippy::exhaustive_enums)]
11+
pub enum State {
12+
/// Editing todo at start of a rebase.
13+
Initial,
14+
/// Editing todo in the middle of a rebase with --edit.
15+
Edit,
16+
/// Editing the todo file for git-revise
17+
Revise,
18+
}
19+
20+
pub(crate) fn detect_state(filepath: &Path) -> Result<State, IoError> {
21+
if filepath.ends_with("git-revise-todo") {
22+
return Ok(State::Revise);
23+
}
24+
if let Some(parent) = filepath.parent() {
25+
if parent.join("stopped-sha").try_exists().map_err(|err| {
26+
IoError::FileRead {
27+
file: PathBuf::from(parent),
28+
cause: FileReadErrorCause::from(err),
29+
}
30+
})? {
31+
return Ok(State::Edit);
32+
}
33+
}
34+
return Ok(State::Initial);
35+
}
36+
37+
impl State {}
38+
39+
impl Display for State {
40+
#[inline]
41+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42+
write!(f, "{}", match *self {
43+
Self::Initial => "initial",
44+
Self::Edit => "edit",
45+
Self::Revise => "revise",
46+
})
47+
}
48+
}
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use rstest::rstest;
53+
54+
use super::*;
55+
56+
#[rstest]
57+
#[case::edit(State::Initial, "initial")]
58+
#[case::edit(State::Edit, "edit")]
59+
#[case::edit(State::Revise, "revise")]
60+
fn to_string(#[case] action: State, #[case] expected: &str) {
61+
assert_eq!(format!("{action}"), expected);
62+
}
63+
}

0 commit comments

Comments
 (0)