Skip to content

Commit

Permalink
feat: add flag for reading specified puzzle part
Browse files Browse the repository at this point in the history
Add a `--part` flag in the `read` subcommand to display/read the
specified part of the puzzle.

When part 1 is included in display (either by directly specifying
`--part 1`, or by not specifying `--part` flag which defaults to both
part 1 & 2), the `--- Part One ---` subheader is added in the output.
This makes display consistent with the output for part 2
(`--- Part Two ---`, which is included by default), and adds better
indicator for the puzzle sections.

Fixes: #27
  • Loading branch information
tyrone-wu committed Dec 1, 2024
1 parent ebb1069 commit 633f2b8
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
32 changes: 27 additions & 5 deletions aoc-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ pub enum AocError {
#[error("{0} is not a valid Advent of Code day")]
InvalidPuzzleDay(PuzzleDay),

#[error("Puzzle {0} of {1} is still locked")]
LockedPuzzle(PuzzleDay, PuzzleYear),
#[error("Puzzle {0} part {1} of {2} is still locked")]
LockedPuzzle(PuzzleDay, PuzzlePart, PuzzleYear),

#[error("Session cookie file not found in home or config directory")]
SessionFileNotFound,
Expand Down Expand Up @@ -167,7 +167,7 @@ impl AocClient {
if self.day_unlocked() {
Ok(())
} else {
Err(AocError::LockedPuzzle(self.day, self.year))
Err(AocError::LockedPuzzle(self.day, PuzzlePart::PartOne, self.year))
}
}

Expand Down Expand Up @@ -296,9 +296,31 @@ impl AocClient {
Ok(())
}

pub fn show_puzzle(&self) -> AocResult<()> {
pub fn show_puzzle(&self, part: Option<&str>) -> AocResult<()> {
let puzzle_html = self.get_puzzle_html()?;
println!("\n{}", self.html2text(&puzzle_html));

// Grabs the header of the format: `--- Day Foo: Bar ---`
let header_end = puzzle_html
.match_indices("---")
.nth(1)
.map(|(start, _)| start + 3)
.unwrap();
// Grabs content range of our puzzle of interest.
let body_range = match (part, puzzle_html.find("--- Part Two ---")) {
(Some("1"), Some(p2_start)) => header_end..p2_start,
(Some("1"), None) | (None, _) => header_end..puzzle_html.len(),
(Some("2"), Some(p2_start)) => p2_start..puzzle_html.len(),
(Some("2"), None) => return Err(AocError::LockedPuzzle(self.day, PuzzlePart::PartTwo, self.year)),
_ => return Err(AocError::InvalidPuzzlePart),
};
let mut display = puzzle_html[..header_end].to_owned() + "<br>";
if matches!(part, Some("1") | None) {
// Insert `Part One` banner along with header.
display.push_str("--- Part One ---");
}
display.push_str(&puzzle_html[body_range]);

println!("\n{}", self.html2text(&display));
Ok(())
}

Expand Down
6 changes: 5 additions & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ pub enum Command {

/// Read puzzle statement (the default command)
#[command(visible_alias = "r")]
Read,
Read {
/// Puzzle part
#[arg(long, value_parser = ["1", "2"])]
part: Option<String>,
},

/// Submit puzzle answer
#[command(visible_alias = "s")]
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ fn run(args: &Args, client: AocClient) -> AocResult<()> {
Some(Command::PrivateLeaderboard { leaderboard_id }) => {
client.show_private_leaderboard(*leaderboard_id)
}
_ => client.show_puzzle(),
Some(Command::Read { part }) => client.show_puzzle(part.as_deref()),
_ => client.show_puzzle(None),
}
}

0 comments on commit 633f2b8

Please sign in to comment.