mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-09-07 20:02:17 +02:00
Add solutions to bins
This commit is contained in:
parent
990c68efcb
commit
beb7b24e8e
@ -1,2 +1,5 @@
|
||||
// The exercise `intro1` only requires entering `n` in the terminal to go to the next exercise.
|
||||
// It is just an introduction to how Rustlings works.
|
||||
fn main() {
|
||||
// Congratulations, you finished the first exercise 🎉
|
||||
// As an introduction to Rustlings, the first exercise only required
|
||||
// entering `n` in the terminal to go to the next exercise.
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use anyhow::{Context, Result};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::info_file::ExerciseInfo;
|
||||
|
||||
@ -40,6 +41,24 @@ pub fn append_bins(
|
||||
}
|
||||
buf.extend_from_slice(exercise_info.name.as_bytes());
|
||||
buf.extend_from_slice(b".rs\" },\n");
|
||||
|
||||
let sol_path = exercise_info.sol_path();
|
||||
if !Path::new(&sol_path).exists() {
|
||||
continue;
|
||||
}
|
||||
|
||||
buf.extend_from_slice(b" { name = \"");
|
||||
buf.extend_from_slice(exercise_info.name.as_bytes());
|
||||
buf.extend_from_slice(b"_sol");
|
||||
buf.extend_from_slice(b"\", path = \"");
|
||||
buf.extend_from_slice(exercise_path_prefix);
|
||||
buf.extend_from_slice(b"solutions/");
|
||||
if let Some(dir) = &exercise_info.dir {
|
||||
buf.extend_from_slice(dir.as_bytes());
|
||||
buf.push(b'/');
|
||||
}
|
||||
buf.extend_from_slice(exercise_info.name.as_bytes());
|
||||
buf.extend_from_slice(b".rs\" },\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use anyhow::{Context, Error, Result};
|
||||
use std::{
|
||||
fs::{create_dir, create_dir_all, OpenOptions},
|
||||
fs::{create_dir, OpenOptions},
|
||||
io::{self, Write},
|
||||
};
|
||||
|
||||
@ -43,8 +43,8 @@ struct ExerciseFiles {
|
||||
}
|
||||
|
||||
// A directory in the `exercises/` directory.
|
||||
struct ExerciseDir {
|
||||
name: &'static str,
|
||||
pub struct ExerciseDir {
|
||||
pub name: &'static str,
|
||||
readme: &'static [u8],
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ pub struct EmbeddedFiles {
|
||||
/// The content of the `info.toml` file.
|
||||
pub info_file: &'static str,
|
||||
exercise_files: &'static [ExerciseFiles],
|
||||
exercise_dirs: &'static [ExerciseDir],
|
||||
pub exercise_dirs: &'static [ExerciseDir],
|
||||
}
|
||||
|
||||
impl EmbeddedFiles {
|
||||
@ -121,13 +121,9 @@ impl EmbeddedFiles {
|
||||
|
||||
// 14 = 10 + 1 + 3
|
||||
// solutions/ + / + .rs
|
||||
let mut dir_path = String::with_capacity(14 + dir.name.len() + exercise_name.len());
|
||||
dir_path.push_str("solutions/");
|
||||
dir_path.push_str(dir.name);
|
||||
create_dir_all(&dir_path)
|
||||
.with_context(|| format!("Failed to create the directory {dir_path}"))?;
|
||||
|
||||
let mut solution_path = dir_path;
|
||||
let mut solution_path = String::with_capacity(14 + dir.name.len() + exercise_name.len());
|
||||
solution_path.push_str("solutions/");
|
||||
solution_path.push_str(dir.name);
|
||||
solution_path.push('/');
|
||||
solution_path.push_str(exercise_name);
|
||||
solution_path.push_str(".rs");
|
||||
|
@ -49,6 +49,30 @@ impl ExerciseInfo {
|
||||
|
||||
path
|
||||
}
|
||||
|
||||
/// Path to the solution file starting with the `solutions/` directory.
|
||||
pub fn sol_path(&self) -> String {
|
||||
let mut path = if let Some(dir) = &self.dir {
|
||||
// 14 = 10 + 1 + 3
|
||||
// solutions/ + / + .rs
|
||||
let mut path = String::with_capacity(14 + dir.len() + self.name.len());
|
||||
path.push_str("solutions/");
|
||||
path.push_str(dir);
|
||||
path.push('/');
|
||||
path
|
||||
} else {
|
||||
// 13 = 10 + 3
|
||||
// solutions/ + .rs
|
||||
let mut path = String::with_capacity(13 + self.name.len());
|
||||
path.push_str("solutions/");
|
||||
path
|
||||
};
|
||||
|
||||
path.push_str(&self.name);
|
||||
path.push_str(".rs");
|
||||
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
/// The deserialized `info.toml` file.
|
||||
|
20
src/init.rs
20
src/init.rs
@ -34,6 +34,20 @@ pub fn init() -> Result<()> {
|
||||
.init_exercises_dir(&info_file.exercises)
|
||||
.context("Failed to initialize the `rustlings/exercises` directory")?;
|
||||
|
||||
create_dir("solutions").context("Failed to create the `solutions/` directory")?;
|
||||
for dir in EMBEDDED_FILES.exercise_dirs {
|
||||
let mut dir_path = String::with_capacity(10 + dir.name.len());
|
||||
dir_path.push_str("solutions/");
|
||||
dir_path.push_str(dir.name);
|
||||
create_dir(&dir_path)
|
||||
.with_context(|| format!("Failed to create the directory {dir_path}"))?;
|
||||
}
|
||||
for exercise_info in &info_file.exercises {
|
||||
let solution_path = exercise_info.sol_path();
|
||||
fs::write(&solution_path, INIT_SOLUTION_FILE)
|
||||
.with_context(|| format!("Failed to create the file {solution_path}"))?;
|
||||
}
|
||||
|
||||
let current_cargo_toml = include_str!("../dev-Cargo.toml");
|
||||
// Skip the first line (comment).
|
||||
let newline_ind = current_cargo_toml
|
||||
@ -72,6 +86,12 @@ pub fn init() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
const INIT_SOLUTION_FILE: &[u8] = b"fn main() {
|
||||
// DON'T EDIT THIS SOLUTION FILE!
|
||||
// It will be automatically filled after you finish the exercise.
|
||||
}
|
||||
";
|
||||
|
||||
const GITIGNORE: &[u8] = b".rustlings-state.txt
|
||||
solutions
|
||||
Cargo.lock
|
||||
|
Loading…
Reference in New Issue
Block a user