mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-01-14 00:00:02 +03:00
hold replacer in app_state insted of main / watcher
This commit is contained in:
parent
5cd711e909
commit
6760560920
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
embedded::EMBEDDED_FILES,
|
embedded::EMBEDDED_FILES,
|
||||||
exercise::{Exercise, RunnableExercise},
|
exercise::{Exercise, RunnableExercise},
|
||||||
info_file::ExerciseInfo,
|
info_file::ExerciseInfo,
|
||||||
term::{self, CheckProgressVisualizer},
|
term::{self, CheckProgressVisualizer}, url_replacer::UrlReplacer,
|
||||||
};
|
};
|
||||||
|
|
||||||
const STATE_FILE_NAME: &str = ".rustlings-state.txt";
|
const STATE_FILE_NAME: &str = ".rustlings-state.txt";
|
||||||
|
@ -68,6 +68,7 @@ impl AppState {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
exercise_infos: Vec<ExerciseInfo>,
|
exercise_infos: Vec<ExerciseInfo>,
|
||||||
final_message: String,
|
final_message: String,
|
||||||
|
base_url: Option<String>,
|
||||||
) -> Result<(Self, StateFileStatus)> {
|
) -> Result<(Self, StateFileStatus)> {
|
||||||
let cmd_runner = CmdRunner::build()?;
|
let cmd_runner = CmdRunner::build()?;
|
||||||
let mut state_file = OpenOptions::new()
|
let mut state_file = OpenOptions::new()
|
||||||
|
@ -80,6 +81,13 @@ impl AppState {
|
||||||
format!("Failed to open or create the state file {STATE_FILE_NAME}")
|
format!("Failed to open or create the state file {STATE_FILE_NAME}")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
// replacer for rustbook url
|
||||||
|
let url_replacer = if let Some(url) = &base_url {
|
||||||
|
Some(UrlReplacer::new(&url))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let dir_canonical_path = term::canonicalize("exercises");
|
let dir_canonical_path = term::canonicalize("exercises");
|
||||||
let mut exercises = exercise_infos
|
let mut exercises = exercise_infos
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -90,7 +98,11 @@ impl AppState {
|
||||||
let path = exercise_info.path().leak();
|
let path = exercise_info.path().leak();
|
||||||
let name = exercise_info.name.leak();
|
let name = exercise_info.name.leak();
|
||||||
let dir = exercise_info.dir.map(|dir| &*dir.leak());
|
let dir = exercise_info.dir.map(|dir| &*dir.leak());
|
||||||
let hint = exercise_info.hint.leak().trim_ascii();
|
let mut hint = exercise_info.hint.leak().trim_ascii();
|
||||||
|
|
||||||
|
if let Some(replacer) = &url_replacer {
|
||||||
|
hint = replacer.replace(&hint).leak();
|
||||||
|
}
|
||||||
|
|
||||||
let canonical_path = dir_canonical_path.as_deref().map(|dir_canonical_path| {
|
let canonical_path = dir_canonical_path.as_deref().map(|dir_canonical_path| {
|
||||||
let mut canonical_path;
|
let mut canonical_path;
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -8,7 +8,7 @@ use std::{
|
||||||
};
|
};
|
||||||
use term::{clear_terminal, press_enter_prompt};
|
use term::{clear_terminal, press_enter_prompt};
|
||||||
|
|
||||||
use self::{app_state::AppState, dev::DevCommands, info_file::InfoFile, url_replacer::UrlReplacer};
|
use self::{app_state::AppState, dev::DevCommands, info_file::InfoFile};
|
||||||
|
|
||||||
mod app_state;
|
mod app_state;
|
||||||
mod cargo_toml;
|
mod cargo_toml;
|
||||||
|
@ -99,6 +99,7 @@ fn main() -> Result<ExitCode> {
|
||||||
let (mut app_state, state_file_status) = AppState::new(
|
let (mut app_state, state_file_status) = AppState::new(
|
||||||
info_file.exercises,
|
info_file.exercises,
|
||||||
info_file.final_message.unwrap_or_default(),
|
info_file.final_message.unwrap_or_default(),
|
||||||
|
args.base_url,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Show the welcome message if the state file doesn't exist yet.
|
// Show the welcome message if the state file doesn't exist yet.
|
||||||
|
@ -186,13 +187,7 @@ fn main() -> Result<ExitCode> {
|
||||||
app_state.set_current_exercise_by_name(&name)?;
|
app_state.set_current_exercise_by_name(&name)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let hint = app_state.current_exercise().hint;
|
println!("{}", app_state.current_exercise().hint);
|
||||||
if let Some(base_url) = args.base_url {
|
|
||||||
let replacer = UrlReplacer::new(base_url);
|
|
||||||
println!("{}", replacer.replace(hint));
|
|
||||||
} else {
|
|
||||||
println!("{}", hint);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
// Handled in an earlier match.
|
// Handled in an earlier match.
|
||||||
Some(Subcommands::Init | Subcommands::Dev(_)) => (),
|
Some(Subcommands::Init | Subcommands::Dev(_)) => (),
|
||||||
|
|
|
@ -5,18 +5,20 @@ pub struct UrlReplacer {
|
||||||
const EN_BASE_URL: &str = "https://doc.rust-lang.org/book";
|
const EN_BASE_URL: &str = "https://doc.rust-lang.org/book";
|
||||||
|
|
||||||
impl UrlReplacer {
|
impl UrlReplacer {
|
||||||
pub fn new(mut base_url: String) -> Self {
|
/// this fn will trim url end with '/'
|
||||||
base_url = if base_url.ends_with('/') {
|
pub fn new(base_url: &String) -> Self {
|
||||||
|
let url = if base_url.ends_with('/') {
|
||||||
base_url.trim_end_matches('/').to_owned()
|
base_url.trim_end_matches('/').to_owned()
|
||||||
} else {
|
} else {
|
||||||
base_url
|
base_url.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
base_url
|
base_url: url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// replace rustbook url
|
||||||
pub fn replace(&self, hint: &str) -> String {
|
pub fn replace(&self, hint: &str) -> String {
|
||||||
hint.replace(EN_BASE_URL, &self.base_url)
|
hint.replace(EN_BASE_URL, &self.base_url)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +32,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn non_rustbook_url() {
|
fn non_rustbook_url() {
|
||||||
let replacer = UrlReplacer::new(String::from(TEST_DOMAIN));
|
let replacer = UrlReplacer::new(&String::from(TEST_DOMAIN));
|
||||||
|
|
||||||
let hint = "\
|
let hint = "\
|
||||||
hints (...) lines (...)
|
hints (...) lines (...)
|
||||||
|
@ -42,7 +44,7 @@ link: https://example.com/ch03-02-data-types.html";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn replace_rustbook_url() {
|
fn replace_rustbook_url() {
|
||||||
let replacer = UrlReplacer::new(String::from(TEST_DOMAIN));
|
let replacer = UrlReplacer::new(&String::from(TEST_DOMAIN));
|
||||||
|
|
||||||
let hint = "\
|
let hint = "\
|
||||||
hints (...) lines (...)
|
hints (...) lines (...)
|
||||||
|
@ -55,7 +57,10 @@ link: https://doc.rust-kr.org/ch03-02-data-types.html", replacer.replace(hint));
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn trim_end_with_slash() {
|
fn trim_end_with_slash() {
|
||||||
let replacer = UrlReplacer::new(String::from(TEST_DOMAIN));
|
let mut domain = String::from(TEST_DOMAIN);
|
||||||
|
domain.push('/');
|
||||||
|
|
||||||
|
let replacer = UrlReplacer::new(&domain);
|
||||||
|
|
||||||
assert_eq!(TEST_DOMAIN, replacer.base_url);
|
assert_eq!(TEST_DOMAIN, replacer.base_url);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue