diff --git a/src/project.rs b/src/project.rs index 4d29c72a..16c3a7cf 100644 --- a/src/project.rs +++ b/src/project.rs @@ -111,8 +111,13 @@ impl Project { pub fn load_from_slice( contents: &[u8], project_file_location: &Path, - ) -> Result { - let mut project: Self = serde_json::from_slice(&contents)?; + ) -> Result { + let mut project: Self = + serde_json::from_slice(&contents).map_err(|source| Error::Json { + source, + path: project_file_location.to_owned(), + })?; + project.file_location = project_file_location.to_path_buf(); project.check_compatibility(); Ok(project) diff --git a/src/serve_session.rs b/src/serve_session.rs index 1164dc5a..d43d4981 100644 --- a/src/serve_session.rs +++ b/src/serve_session.rs @@ -1,11 +1,14 @@ use std::{ + borrow::Cow, collections::HashSet, + io, path::{Path, PathBuf}, sync::{Arc, Mutex, MutexGuard}, time::Instant, }; use crossbeam_channel::Sender; +use memofs::IoResultExt; use memofs::Vfs; use rbx_dom_weak::RbxInstanceProperties; use thiserror::Error; @@ -97,11 +100,23 @@ impl ServeSession { log::trace!("Starting new ServeSession at path {}", start_path.display()); - log::debug!("Loading project file from {}", start_path.display()); - let root_project = - Project::load_fuzzy(start_path)?.ok_or_else(|| ServeSessionError::NoProjectFound { - path: start_path.to_owned(), - })?; + let project_path; + if Project::is_project_file(start_path) { + project_path = Cow::Borrowed(start_path); + } else { + project_path = Cow::Owned(start_path.join("default.project.json")); + } + + log::debug!("Loading project file from {}", project_path.display()); + + let root_project = match vfs.read(&project_path).with_not_found()? { + Some(contents) => Project::load_from_slice(&contents, &project_path)?, + None => { + return Err(ServeSessionError::NoProjectFound { + path: project_path.to_path_buf(), + }); + } + }; let mut tree = RojoTree::new(InstancePropertiesWithMeta { properties: RbxInstanceProperties { @@ -206,6 +221,12 @@ pub enum ServeSessionError { )] NoProjectFound { path: PathBuf }, + #[error(transparent)] + Io { + #[from] + source: io::Error, + }, + #[error(transparent)] Project { #[from] diff --git a/src/snapshot_middleware/error.rs b/src/snapshot_middleware/error.rs index a1c1665d..7e0e3847 100644 --- a/src/snapshot_middleware/error.rs +++ b/src/snapshot_middleware/error.rs @@ -2,6 +2,8 @@ use std::{io, path::PathBuf}; use thiserror::Error; +use crate::project::ProjectError; + #[derive(Debug, Error)] pub enum SnapshotError { #[error("file name had malformed Unicode")] @@ -14,10 +16,7 @@ pub enum SnapshotError { }, #[error("malformed project file at path {}", .path.display())] - MalformedProject { - source: serde_json::Error, - path: PathBuf, - }, + MalformedProject { source: ProjectError, path: PathBuf }, #[error("malformed .model.json file at path {}", .path.display())] MalformedModelJson { @@ -62,7 +61,7 @@ impl SnapshotError { } } - pub(crate) fn malformed_project(source: serde_json::Error, path: impl Into) -> Self { + pub(crate) fn malformed_project(source: ProjectError, path: impl Into) -> Self { Self::MalformedProject { source, path: path.into(),