diff --git a/rustlings-macros/src/lib.rs b/rustlings-macros/src/lib.rs index db758d59..40eebc16 100644 --- a/rustlings-macros/src/lib.rs +++ b/rustlings-macros/src/lib.rs @@ -16,8 +16,16 @@ struct InfoFile<'a> { #[proc_macro] pub fn include_files(_: TokenStream) -> TokenStream { - let info_file = include_str!("../info.toml"); - let exercises = toml::de::from_str::(info_file) + // Remove `\r` on Windows + let info_file = String::from_utf8( + include_bytes!("../info.toml") + .iter() + .copied() + .filter(|c| *c != b'\r') + .collect(), + ) + .expect("Failed to parse `info.toml` as UTF8"); + let exercises = toml::de::from_str::(&info_file) .expect("Failed to parse `info.toml`") .exercises; diff --git a/src/info_file.rs b/src/info_file.rs index 23df0d16..13206fd8 100644 --- a/src/info_file.rs +++ b/src/info_file.rs @@ -94,10 +94,17 @@ impl InfoFile { /// Community exercises: Parse the `info.toml` file in the current directory. pub fn parse() -> Result { // Read a local `info.toml` if it exists. - let slf = match fs::read_to_string("info.toml") { - // Leaking is fine since the info file is used until the end of the program. - Ok(file_content) => toml::de::from_str::(file_content.leak()) - .context("Failed to parse the `info.toml` file")?, + let slf = match fs::read("info.toml") { + Ok(file_content) => { + // Remove `\r` on Windows. + // Leaking is fine since the info file is used until the end of the program. + let file_content = + String::from_utf8(file_content.into_iter().filter(|c| *c != b'\r').collect()) + .context("Failed to parse `info.toml` as UTF8")? + .leak(); + toml::de::from_str::(file_content) + .context("Failed to parse the `info.toml` file")? + } Err(e) => { if e.kind() == ErrorKind::NotFound { return toml::de::from_str(EMBEDDED_FILES.info_file)