State -> StateFile

This commit is contained in:
mo8it 2024-04-07 19:01:08 +02:00
parent 8c31d38fa1
commit 3bd26c7a24
4 changed files with 24 additions and 23 deletions

View file

@ -14,7 +14,7 @@ use ratatui::{
};
use std::io;
use crate::{exercise::Exercise, state::State};
use crate::{exercise::Exercise, state_file::StateFile};
struct UiState<'a> {
pub table: Table<'a>,
@ -25,7 +25,7 @@ struct UiState<'a> {
impl<'a> UiState<'a> {
pub fn rows<'s, 'i>(
state: &'s State,
state_file: &'s StateFile,
exercises: &'a [Exercise],
) -> impl Iterator<Item = Row<'a>> + 'i
where
@ -34,10 +34,10 @@ impl<'a> UiState<'a> {
{
exercises
.iter()
.zip(state.progress())
.zip(state_file.progress())
.enumerate()
.map(|(ind, (exercise, done))| {
let next = if ind == state.next_exercise_ind() {
let next = if ind == state_file.next_exercise_ind() {
">>>>".bold().red()
} else {
Span::default()
@ -58,7 +58,7 @@ impl<'a> UiState<'a> {
})
}
pub fn new(state: &State, exercises: &'a [Exercise]) -> Self {
pub fn new(state_file: &StateFile, exercises: &'a [Exercise]) -> Self {
let header = Row::new(["Next", "State", "Name", "Path"]);
let max_name_len = exercises
@ -74,7 +74,7 @@ impl<'a> UiState<'a> {
Constraint::Fill(1),
];
let rows = Self::rows(state, exercises);
let rows = Self::rows(state_file, exercises);
let table = Table::new(rows, widths)
.header(header)
@ -147,7 +147,7 @@ impl<'a> UiState<'a> {
}
}
pub fn list(state: &mut State, exercises: &[Exercise]) -> Result<()> {
pub fn list(state_file: &mut StateFile, exercises: &[Exercise]) -> Result<()> {
let mut stdout = io::stdout().lock();
stdout.execute(EnterAlternateScreen)?;
enable_raw_mode()?;
@ -155,7 +155,7 @@ pub fn list(state: &mut State, exercises: &[Exercise]) -> Result<()> {
let mut terminal = Terminal::new(CrosstermBackend::new(&mut stdout))?;
terminal.clear()?;
let mut ui_state = UiState::new(state, exercises);
let mut ui_state = UiState::new(state_file, exercises);
'outer: loop {
terminal.draw(|frame| ui_state.draw(frame))?;
@ -183,8 +183,8 @@ pub fn list(state: &mut State, exercises: &[Exercise]) -> Result<()> {
KeyCode::Home | KeyCode::Char('g') => ui_state.select_first(),
KeyCode::End | KeyCode::Char('G') => ui_state.select_last(),
KeyCode::Char('c') => {
state.set_next_exercise_ind(ui_state.selected)?;
ui_state.table = ui_state.table.rows(UiState::rows(state, exercises));
state_file.set_next_exercise_ind(ui_state.selected)?;
ui_state.table = ui_state.table.rows(UiState::rows(state_file, exercises));
}
_ => (),
}

View file

@ -1,11 +1,6 @@
use crate::consts::WELCOME;
use crate::embedded::{WriteStrategy, EMBEDDED_FILES};
use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use anyhow::{bail, Context, Result};
use clap::{Parser, Subcommand};
use state::State;
use state_file::StateFile;
use std::path::Path;
use std::process::exit;
use verify::VerifyState;
@ -16,10 +11,16 @@ mod exercise;
mod init;
mod list;
mod run;
mod state;
mod state_file;
mod verify;
mod watch;
use crate::consts::WELCOME;
use crate::embedded::{WriteStrategy, EMBEDDED_FILES};
use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
/// Rustlings is a collection of small exercises to get you used to writing and reading Rust code
#[derive(Parser)]
#[command(version)]
@ -85,7 +86,7 @@ If you are just starting with Rustlings, run the command `rustlings init` to ini
exit(1);
}
let mut state = State::read_or_default(&exercises);
let mut state = StateFile::read_or_default(&exercises);
match args.command {
None | Some(Subcommands::Watch) => {

View file

@ -5,12 +5,12 @@ use std::fs;
use crate::exercise::Exercise;
#[derive(Serialize, Deserialize)]
pub struct State {
pub struct StateFile {
next_exercise_ind: usize,
progress: Vec<bool>,
}
impl State {
impl StateFile {
fn read(exercises: &[Exercise]) -> Option<Self> {
let file_content = fs::read(".rustlings.json").ok()?;

View file

@ -18,7 +18,7 @@ use std::{
use crate::{
exercise::{self, Exercise},
state::State,
state_file::StateFile,
};
enum Event {
@ -151,14 +151,14 @@ You can keep working on this exercise or jump into the next one by removing the
}
}
pub fn watch(state: &State, exercises: &[Exercise]) -> Result<()> {
pub fn watch(state_file: &StateFile, exercises: &[Exercise]) -> Result<()> {
let (tx, rx) = channel();
let mut debouncer = new_debouncer(Duration::from_secs(1), tx)?;
debouncer
.watcher()
.watch(Path::new("exercises"), RecursiveMode::Recursive)?;
let current_exercise_ind = state.next_exercise_ind();
let current_exercise_ind = state_file.next_exercise_ind();
let exercise = &exercises[current_exercise_ind];