From 8ddbf9635d21a4c0306bd31cca5c4077693ca917 Mon Sep 17 00:00:00 2001 From: mo8it Date: Mon, 25 Mar 2024 23:01:56 +0100 Subject: [PATCH] Add write_project_json --- src/main.rs | 11 +++------ src/project.rs | 63 +++++++++++++++++++++++--------------------------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1f260ab7..46aaf1f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use crate::exercise::{Exercise, ExerciseList}; -use crate::project::RustAnalyzerProject; +use crate::project::write_project_json; use crate::run::{reset, run}; use crate::verify::verify; use anyhow::Result; @@ -204,13 +204,8 @@ fn main() -> Result<()> { } Subcommands::Lsp => { - let mut project = RustAnalyzerProject::build()?; - project - .exercises_to_json(exercises) - .expect("Couldn't parse rustlings exercises files"); - - if project.write_to_disk().is_err() { - println!("Failed to write rust-project.json to disk for rust-analyzer"); + if let Err(e) = write_project_json(exercises) { + println!("Failed to write rust-project.json to disk for rust-analyzer: {e}"); } else { println!("Successfully generated rust-project.json"); println!("rust-analyzer will now parse exercises, restart your language server or editor") diff --git a/src/project.rs b/src/project.rs index 54cffe12..acf011d3 100644 --- a/src/project.rs +++ b/src/project.rs @@ -1,7 +1,6 @@ use anyhow::{Context, Result}; use serde::Serialize; use std::env; -use std::error::Error; use std::path::PathBuf; use std::process::{Command, Stdio}; @@ -10,7 +9,7 @@ use crate::exercise::Exercise; /// Contains the structure of resulting rust-project.json file /// and functions to build the data required to create the file #[derive(Serialize)] -pub struct RustAnalyzerProject { +struct RustAnalyzerProject { sysroot_src: PathBuf, crates: Vec, } @@ -25,12 +24,22 @@ struct Crate { } impl RustAnalyzerProject { - pub fn build() -> Result { - // check if RUST_SRC_PATH is set + fn build(exercises: Vec) -> Result { + let crates = exercises + .into_iter() + .map(|exercise| Crate { + root_module: exercise.path, + edition: "2021", + deps: Vec::new(), + // This allows rust_analyzer to work inside #[test] blocks + cfg: ["test"], + }) + .collect(); + if let Some(path) = env::var_os("RUST_SRC_PATH") { return Ok(Self { sysroot_src: PathBuf::from(path), - crates: Vec::new(), + crates, }); } @@ -53,35 +62,21 @@ impl RustAnalyzerProject { Ok(Self { sysroot_src, - crates: Vec::new(), + crates, }) } - - /// Write rust-project.json to disk - pub fn write_to_disk(&self) -> Result<(), std::io::Error> { - // Using the capacity 2^14 = 16384 since the file length in bytes is higher than 2^13. - // The final length is not known exactly because it depends on the user's sysroot path, - // the current number of exercises etc. - let mut buf = Vec::with_capacity(16384); - serde_json::to_writer(&mut buf, &self).expect("Failed to serialize to JSON"); - std::fs::write("rust-project.json", buf)?; - Ok(()) - } - - /// Parse the exercises folder for .rs files, any matches will create - /// a new `crate` in rust-project.json which allows rust-analyzer to - /// treat it like a normal binary - pub fn exercises_to_json(&mut self, exercises: Vec) -> Result<(), Box> { - self.crates = exercises - .into_iter() - .map(|exercise| Crate { - root_module: exercise.path, - edition: "2021", - deps: Vec::new(), - // This allows rust_analyzer to work inside #[test] blocks - cfg: ["test"], - }) - .collect(); - Ok(()) - } +} + +/// Write `rust-project.json` to disk. +pub fn write_project_json(exercises: Vec) -> Result<()> { + let content = RustAnalyzerProject::build(exercises)?; + + // Using the capacity 2^14 since the file length in bytes is higher than 2^13. + // The final length is not known exactly because it depends on the user's sysroot path, + // the current number of exercises etc. + let mut buf = Vec::with_capacity(1 << 14); + serde_json::to_writer(&mut buf, &content)?; + std::fs::write("rust-project.json", buf)?; + + Ok(()) }