1
0
mirror of https://github.com/rust-lang/rustlings.git synced 2024-09-16 10:51:42 +02:00

Document info_file

This commit is contained in:
mo8it 2024-05-13 22:02:45 +02:00
parent d48e86b154
commit a67e63cce0
2 changed files with 35 additions and 11 deletions

View File

@ -17,10 +17,9 @@ use crate::{
/// The initial capacity of the output buffer. /// The initial capacity of the output buffer.
pub const OUTPUT_CAPACITY: usize = 1 << 14; pub const OUTPUT_CAPACITY: usize = 1 << 14;
/// See `info_file::ExerciseInfo`
pub struct Exercise { pub struct Exercise {
/// Directory name.
pub dir: Option<&'static str>, pub dir: Option<&'static str>,
/// Exercise's unique name.
pub name: &'static str, pub name: &'static str,
/// Path of the exercise file starting with the `exercises/` directory. /// Path of the exercise file starting with the `exercises/` directory.
pub path: &'static str, pub path: &'static str,

View File

@ -4,44 +4,69 @@ use std::{fs, io::ErrorKind};
use crate::embedded::EMBEDDED_FILES; use crate::embedded::EMBEDDED_FILES;
// Deserialized from the `info.toml` file. /// Deserialized from the `info.toml` file.
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct ExerciseInfo { pub struct ExerciseInfo {
// Name of the exercise /// Exercise's unique name.
pub name: String, pub name: String,
// The exercise's directory inside the `exercises` directory /// Exercise's directory name inside the `exercises/` directory.
pub dir: Option<String>, pub dir: Option<String>,
#[serde(default = "default_true")] #[serde(default = "default_true")]
/// Run `cargo test` on the exercise.
pub test: bool, pub test: bool,
/// Deny all Clippy warnings.
#[serde(default)] #[serde(default)]
pub strict_clippy: bool, pub strict_clippy: bool,
// The hint text associated with the exercise /// The exercise's hint to be shown to the user on request.
pub hint: String, pub hint: String,
} }
#[inline] #[inline(always)]
const fn default_true() -> bool { const fn default_true() -> bool {
true true
} }
impl ExerciseInfo { impl ExerciseInfo {
/// Path to the exercise file starting with the `exercises/` directory.
pub fn path(&self) -> String { pub fn path(&self) -> String {
if let Some(dir) = &self.dir { let mut path = if let Some(dir) = &self.dir {
format!("exercises/{dir}/{}.rs", self.name) // 14 = 10 + 1 + 3
// exercises/ + / + .rs
let mut path = String::with_capacity(14 + dir.len() + self.name.len());
path.push_str("exercises/");
path.push_str(dir);
path.push('/');
path
} else { } else {
format!("exercises/{}.rs", self.name) // 13 = 10 + 3
} // exercises/ + .rs
let mut path = String::with_capacity(13 + self.name.len());
path.push_str("exercises/");
path
};
path.push_str(&self.name);
path.push_str(".rs");
path
} }
} }
/// The deserialized `info.toml` file.
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct InfoFile { pub struct InfoFile {
/// For possible breaking changes in the future for third-party exercises.
pub format_version: u8, pub format_version: u8,
/// Shown to users when starting with the exercises.
pub welcome_message: Option<String>, pub welcome_message: Option<String>,
/// Shown to users after finishing all exercises.
pub final_message: Option<String>, pub final_message: Option<String>,
/// List of all exercises.
pub exercises: Vec<ExerciseInfo>, pub exercises: Vec<ExerciseInfo>,
} }
impl InfoFile { impl InfoFile {
/// Official exercises: Parse the embedded `info.toml` file.
/// Third-party exercises: Parse the `info.toml` file in the current directory.
pub fn parse() -> Result<Self> { pub fn parse() -> Result<Self> {
// Read a local `info.toml` if it exists. // Read a local `info.toml` if it exists.
let slf = match fs::read_to_string("info.toml") { let slf = match fs::read_to_string("info.toml") {