@@ -6,19 +6,19 @@ use crate::{embedded::EMBEDDED_FILES, exercise::RunnableExercise};
66
77/// Deserialized from the `info.toml` file.
88#[ derive( Deserialize ) ]
9- pub struct ExerciseInfo {
9+ pub struct ExerciseInfo < ' a > {
1010 /// Exercise's unique name.
11- pub name : & ' static str ,
11+ pub name : & ' a str ,
1212 /// Exercise's directory name inside the `exercises/` directory.
13- pub dir : Option < & ' static str > ,
13+ pub dir : Option < & ' a str > ,
1414 /// Run `cargo test` on the exercise.
1515 #[ serde( default = "default_true" ) ]
1616 pub test : bool ,
1717 /// Deny all Clippy warnings.
1818 #[ serde( default ) ]
1919 pub strict_clippy : bool ,
2020 /// The exercise's hint to be shown to the user on request.
21- pub hint : & ' static str ,
21+ pub hint : String ,
2222 /// The exercise is already solved. Ignore it when checking that all exercises are unsolved.
2323 #[ serde( default ) ]
2424 pub skip_check_unsolved : bool ,
@@ -27,7 +27,7 @@ const fn default_true() -> bool {
2727 true
2828}
2929
30- impl ExerciseInfo {
30+ impl ExerciseInfo < ' _ > {
3131 /// Path to the exercise file starting with the `exercises/` directory.
3232 pub fn path ( & self ) -> String {
3333 let mut path = if let Some ( dir) = self . dir {
@@ -53,7 +53,7 @@ impl ExerciseInfo {
5353 }
5454}
5555
56- impl RunnableExercise for ExerciseInfo {
56+ impl RunnableExercise for ExerciseInfo < ' _ > {
5757 fn name ( & self ) -> & str {
5858 self . name
5959 }
@@ -77,27 +77,25 @@ pub struct InfoFile {
7777 /// For possible breaking changes in the future for community exercises.
7878 pub format_version : u8 ,
7979 /// Shown to users when starting with the exercises.
80- pub welcome_message : Option < & ' static str > ,
80+ #[ serde( default ) ]
81+ pub welcome_message : String ,
8182 /// Shown to users after finishing all exercises.
82- pub final_message : Option < & ' static str > ,
83+ #[ serde( default ) ]
84+ pub final_message : String ,
8385 /// List of all exercises.
84- pub exercises : Vec < ExerciseInfo > ,
86+ #[ serde( borrow) ]
87+ pub exercises : Vec < ExerciseInfo < ' static > > ,
8588}
8689
8790impl InfoFile {
8891 /// Official exercises: Parse the embedded `info.toml` file.
8992 /// Community exercises: Parse the `info.toml` file in the current directory.
9093 pub fn parse ( ) -> Result < Self > {
9194 // Read a local `info.toml` if it exists.
92- let slf = match fs:: read ( "info.toml" ) {
95+ let slf = match fs:: read_to_string ( "info.toml" ) {
9396 Ok ( file_content) => {
94- // Remove `\r` on Windows.
95- // Leaking is fine since the info file is used until the end of the program.
96- let file_content =
97- String :: from_utf8 ( file_content. into_iter ( ) . filter ( |c| * c != b'\r' ) . collect ( ) )
98- . context ( "Failed to parse `info.toml` as UTF8" ) ?
99- . leak ( ) ;
100- toml:: de:: from_str :: < Self > ( file_content)
97+ // LEAKING: The info file is used until the end of the program.
98+ toml:: de:: from_str :: < Self > ( file_content. leak ( ) )
10199 . context ( "Failed to parse the `info.toml` file" ) ?
102100 }
103101 Err ( e) => {
0 commit comments