mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-24 22:50:26 +00:00
Compare commits
13 commits
e8ec2fddf9
...
a944fc73f4
Author | SHA1 | Date | |
---|---|---|---|
|
a944fc73f4 | ||
|
26cf4989a2 | ||
|
6e60f441e9 | ||
|
275071b740 | ||
|
e5f0a8f997 | ||
|
027cbdb629 | ||
|
6760560920 | ||
|
5cd711e909 | ||
|
1ffe7fc837 | ||
|
509d240d2b | ||
|
2c09341074 | ||
|
96816a7b78 | ||
|
d49f192835 |
4 changed files with 84 additions and 2 deletions
|
@ -19,7 +19,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn yummy_food() {
|
||||
// This means that calling `picky_eater` with the argument "food" should return "Yummy!".
|
||||
// This means that calling `picky_eater` with the argument "strawberry" should return "Yummy!".
|
||||
assert_eq!(picky_eater("strawberry"), "Yummy!");
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ use crate::{
|
|||
exercise::{Exercise, RunnableExercise},
|
||||
info_file::ExerciseInfo,
|
||||
term::{self, CheckProgressVisualizer},
|
||||
url_replacer::UrlReplacer,
|
||||
};
|
||||
|
||||
const STATE_FILE_NAME: &str = ".rustlings-state.txt";
|
||||
|
@ -68,6 +69,7 @@ impl AppState {
|
|||
pub fn new(
|
||||
exercise_infos: Vec<ExerciseInfo>,
|
||||
final_message: String,
|
||||
base_url: Option<String>,
|
||||
) -> Result<(Self, StateFileStatus)> {
|
||||
let cmd_runner = CmdRunner::build()?;
|
||||
let mut state_file = OpenOptions::new()
|
||||
|
@ -80,6 +82,9 @@ impl AppState {
|
|||
format!("Failed to open or create the state file {STATE_FILE_NAME}")
|
||||
})?;
|
||||
|
||||
// replacer for rustbook url
|
||||
let url_replacer = base_url.as_ref().map(|url| UrlReplacer::new(url));
|
||||
|
||||
let dir_canonical_path = term::canonicalize("exercises");
|
||||
let mut exercises = exercise_infos
|
||||
.into_iter()
|
||||
|
@ -90,7 +95,11 @@ impl AppState {
|
|||
let path = exercise_info.path().leak();
|
||||
let name = exercise_info.name.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 mut canonical_path;
|
||||
|
|
|
@ -21,6 +21,7 @@ mod init;
|
|||
mod list;
|
||||
mod run;
|
||||
mod term;
|
||||
mod url_replacer;
|
||||
mod watch;
|
||||
|
||||
const CURRENT_FORMAT_VERSION: u8 = 1;
|
||||
|
@ -35,6 +36,10 @@ struct Args {
|
|||
/// Only use this if Rustlings fails to detect exercise file changes.
|
||||
#[arg(long)]
|
||||
manual_run: bool,
|
||||
|
||||
/// Change rustbook url to passed one.
|
||||
#[arg(long)]
|
||||
base_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
@ -94,6 +99,7 @@ fn main() -> Result<ExitCode> {
|
|||
let (mut app_state, state_file_status) = AppState::new(
|
||||
info_file.exercises,
|
||||
info_file.final_message.unwrap_or_default(),
|
||||
args.base_url,
|
||||
)?;
|
||||
|
||||
// Show the welcome message if the state file doesn't exist yet.
|
||||
|
|
67
src/url_replacer.rs
Normal file
67
src/url_replacer.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
pub struct UrlReplacer {
|
||||
base_url: String,
|
||||
}
|
||||
|
||||
const EN_BASE_URL: &str = "https://doc.rust-lang.org/book";
|
||||
|
||||
impl UrlReplacer {
|
||||
/// this fn will trim url end with '/'
|
||||
pub fn new(base_url: &str) -> Self {
|
||||
let url = if base_url.ends_with('/') {
|
||||
base_url.trim_end_matches('/').to_owned()
|
||||
} else {
|
||||
base_url.to_owned()
|
||||
};
|
||||
|
||||
Self { base_url: url }
|
||||
}
|
||||
|
||||
/// replace rustbook url
|
||||
pub fn replace(&self, hint: &str) -> String {
|
||||
hint.replace(EN_BASE_URL, &self.base_url)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const TEST_DOMAIN: &str = "https://doc.rust-kr.org";
|
||||
|
||||
#[test]
|
||||
fn non_rustbook_url() {
|
||||
let replacer = UrlReplacer::new(&String::from(TEST_DOMAIN));
|
||||
|
||||
let hint = "\
|
||||
hints (...) lines (...)
|
||||
link: https://example.com/ch03-02-data-types.html";
|
||||
|
||||
assert_eq!(hint, replacer.replace(hint));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_rustbook_url() {
|
||||
let replacer = UrlReplacer::new(&String::from(TEST_DOMAIN));
|
||||
|
||||
let hint = "\
|
||||
hints (...) lines (...)
|
||||
link: https://doc.rust-lang.org/book/ch03-02-data-types.html";
|
||||
|
||||
assert_eq!(
|
||||
"\
|
||||
hints (...) lines (...)
|
||||
link: https://doc.rust-kr.org/ch03-02-data-types.html",
|
||||
replacer.replace(hint)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trim_end_with_slash() {
|
||||
let mut domain = String::from(TEST_DOMAIN);
|
||||
domain.push('/');
|
||||
|
||||
let replacer = UrlReplacer::new(&domain);
|
||||
|
||||
assert_eq!(TEST_DOMAIN, replacer.base_url);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue