mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-24 06:35:39 +00:00
Foundations for actual 'rojo init' implementation
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
fs,
|
fmt,
|
||||||
|
fs::{self, File},
|
||||||
io,
|
io,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
@@ -127,12 +128,30 @@ impl From<ProjectLoadExactError> for ProjectLoadFuzzyError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
#[fail(display = "Project init error")]
|
pub enum ProjectInitError {
|
||||||
pub struct ProjectInitError;
|
AlreadyExists(PathBuf),
|
||||||
|
IoError(#[fail(cause)] io::Error),
|
||||||
|
SaveError(#[fail(cause)] ProjectSaveError),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ProjectInitError {
|
||||||
|
fn fmt(&self, output: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
ProjectInitError::AlreadyExists(path) => write!(output, "Path {} already exists", path.display()),
|
||||||
|
ProjectInitError::IoError(inner) => write!(output, "IO error: {}", inner),
|
||||||
|
ProjectInitError::SaveError(inner) => write!(output, "{}", inner),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Fail)]
|
#[derive(Debug, Fail)]
|
||||||
#[fail(display = "Project save error")]
|
pub enum ProjectSaveError {
|
||||||
pub struct ProjectSaveError;
|
#[fail(display = "JSON error: {}", _0)]
|
||||||
|
JsonError(#[fail(cause)] serde_json::Error),
|
||||||
|
|
||||||
|
#[fail(display = "IO error: {}", _0)]
|
||||||
|
IoError(#[fail(cause)] io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@@ -180,14 +199,75 @@ pub struct Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Project {
|
impl Project {
|
||||||
pub fn init_place(_project_fuzzy_location: &Path) -> Result<PathBuf, ProjectInitError> {
|
pub fn init_place(project_fuzzy_location: &Path) -> Result<PathBuf, ProjectInitError> {
|
||||||
unimplemented!();
|
let is_exact = project_fuzzy_location.extension().is_some();
|
||||||
|
|
||||||
|
let project_name = if is_exact {
|
||||||
|
project_fuzzy_location.parent().unwrap().file_name().unwrap().to_str().unwrap()
|
||||||
|
} else {
|
||||||
|
project_fuzzy_location.file_name().unwrap().to_str().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Add children for src folder, potentially client, server, and
|
||||||
|
// common?
|
||||||
|
|
||||||
|
let replicated_storage_children = HashMap::new();
|
||||||
|
|
||||||
|
let replicated_storage = ProjectNode::Instance(InstanceProjectNode {
|
||||||
|
class_name: "ReplicatedStorage".to_string(),
|
||||||
|
children: replicated_storage_children,
|
||||||
|
properties: HashMap::new(),
|
||||||
|
metadata: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut root_children = HashMap::new();
|
||||||
|
root_children.insert("ReplicatedStorage".to_string(), replicated_storage);
|
||||||
|
|
||||||
|
let tree = ProjectNode::Instance(InstanceProjectNode {
|
||||||
|
class_name: "DataModel".to_string(),
|
||||||
|
children: root_children,
|
||||||
|
properties: HashMap::new(),
|
||||||
|
metadata: Default::default(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let project = Project {
|
||||||
|
name: project_name.to_string(),
|
||||||
|
tree,
|
||||||
|
serve_port: None,
|
||||||
|
serve_place_ids: None,
|
||||||
|
file_location: project_fuzzy_location.to_path_buf(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Project::init_internal(project_fuzzy_location, &project)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_model(_project_fuzzy_location: &Path) -> Result<PathBuf, ProjectInitError> {
|
pub fn init_model(_project_fuzzy_location: &Path) -> Result<PathBuf, ProjectInitError> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn init_internal(project_fuzzy_location: &Path, project: &Project) -> Result<PathBuf, ProjectInitError> {
|
||||||
|
let is_exact = project_fuzzy_location.extension().is_some();
|
||||||
|
|
||||||
|
let project_location = if is_exact {
|
||||||
|
project_fuzzy_location.to_path_buf()
|
||||||
|
} else {
|
||||||
|
project_fuzzy_location.join(PROJECT_FILENAME)
|
||||||
|
};
|
||||||
|
|
||||||
|
match fs::metadata(&project_location) {
|
||||||
|
Err(error) => match error.kind() {
|
||||||
|
io::ErrorKind::NotFound => {},
|
||||||
|
_ => return Err(ProjectInitError::IoError(error)),
|
||||||
|
},
|
||||||
|
Ok(_) => return Err(ProjectInitError::AlreadyExists(project_location)),
|
||||||
|
}
|
||||||
|
|
||||||
|
project.save(&project_location)
|
||||||
|
.map_err(ProjectInitError::SaveError)?;
|
||||||
|
|
||||||
|
Ok(project_location)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn locate(start_location: &Path) -> Option<PathBuf> {
|
pub fn locate(start_location: &Path) -> Option<PathBuf> {
|
||||||
// TODO: Check for specific error kinds, convert 'not found' to Result.
|
// TODO: Check for specific error kinds, convert 'not found' to Result.
|
||||||
let location_metadata = fs::metadata(start_location).ok()?;
|
let location_metadata = fs::metadata(start_location).ok()?;
|
||||||
@@ -230,10 +310,15 @@ impl Project {
|
|||||||
Ok(parsed.into_project(project_file_location))
|
Ok(parsed.into_project(project_file_location))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(&self) -> Result<(), ProjectSaveError> {
|
pub fn save(&self, path: &Path) -> Result<(), ProjectSaveError> {
|
||||||
let _source_project = self.to_source_project();
|
let source_project = self.to_source_project();
|
||||||
|
let mut file = File::create(path)
|
||||||
|
.map_err(ProjectSaveError::IoError)?;
|
||||||
|
|
||||||
unimplemented!();
|
serde_json::to_writer_pretty(&mut file, &source_project)
|
||||||
|
.map_err(ProjectSaveError::JsonError)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_source_project(&self) -> SourceProject {
|
fn to_source_project(&self) -> SourceProject {
|
||||||
|
|||||||
Reference in New Issue
Block a user