diff --git a/server/src/bin.rs b/server/src/bin.rs index 6db5da5e..9dc1e529 100644 --- a/server/src/bin.rs +++ b/server/src/bin.rs @@ -1,6 +1,9 @@ +#[macro_use] extern crate log; + use std::{ path::{Path, PathBuf}, env, + process, }; use clap::clap_app; @@ -73,9 +76,16 @@ fn main() { let options = commands::BuildOptions { fuzzy_project_path, output_file, + output_kind: None, // TODO: Accept from argument }; - commands::build(&options); + match commands::build(&options) { + Ok(_) => {}, + Err(e) => { + error!("{}", e); + process::exit(1); + }, + } }, _ => { app.print_help().expect("Could not print help text to stdout!"); diff --git a/server/src/commands/build.rs b/server/src/commands/build.rs index d3e81fa2..9ac990f0 100644 --- a/server/src/commands/build.rs +++ b/server/src/commands/build.rs @@ -1,33 +1,76 @@ use std::{ path::PathBuf, fs::File, - process, + fmt, }; use rbxmx; use crate::{ rbx_session::construct_oneoff_tree, - project::Project, + project::{Project, ProjectLoadFuzzyError}, imfs::Imfs, }; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum OutputKind { + Rbxmx, + Rbxlx, +} + +fn detect_output_kind(options: &BuildOptions) -> Option { + match options.output_kind { + Some(output_kind) => Some(output_kind), + None => { + let extension = options.output_file.extension()?.to_str()?; + + match extension { + "rbxlx" => Some(OutputKind::Rbxlx), + "rbxmx" => Some(OutputKind::Rbxmx), + _ => None, + } + }, + } +} + #[derive(Debug)] pub struct BuildOptions { pub fuzzy_project_path: PathBuf, pub output_file: PathBuf, + pub output_kind: Option, } -pub fn build(options: &BuildOptions) { +pub enum BuildError { + UnknownOutputKind, + ProjectLoadError(ProjectLoadFuzzyError), +} + +impl fmt::Display for BuildError { + fn fmt(&self, output: &mut fmt::Formatter) -> fmt::Result { + match self { + BuildError::UnknownOutputKind => { + write!(output, "Could not detect what kind of output file to create") + }, + BuildError::ProjectLoadError(inner) => write!(output, "{}", inner), + } + } +} + +impl From for BuildError { + fn from(error: ProjectLoadFuzzyError) -> BuildError { + BuildError::ProjectLoadError(error) + } +} + +pub fn build(options: &BuildOptions) -> Result<(), BuildError> { + let output_kind = detect_output_kind(options) + .ok_or(BuildError::UnknownOutputKind)?; + + info!("Hoping to generate file of type {:?}", output_kind); + info!("Looking for project at {}", options.fuzzy_project_path.display()); - let project = match Project::load_fuzzy(&options.fuzzy_project_path) { - Ok(project) => project, - Err(error) => { - error!("{}", error); - process::exit(1); - }, - }; + let project = Project::load_fuzzy(&options.fuzzy_project_path)?; info!("Found project at {}", project.file_location.display()); info!("Using project {:#?}", project); @@ -36,10 +79,21 @@ pub fn build(options: &BuildOptions) { .expect("Could not create in-memory filesystem"); let tree = construct_oneoff_tree(&project, &imfs); - let root_id = tree.get_root_id(); let mut file = File::create(&options.output_file) .expect("Could not open output file for write"); - rbxmx::encode(&tree, &[root_id], &mut file); + match output_kind { + OutputKind::Rbxmx => { + let root_id = tree.get_root_id(); + rbxmx::encode(&tree, &[root_id], &mut file); + }, + OutputKind::Rbxlx => { + let root_id = tree.get_root_id(); + let top_level_ids = tree.get_instance(root_id).unwrap().get_children_ids(); + rbxmx::encode(&tree, top_level_ids, &mut file); + }, + } + + Ok(()) } \ No newline at end of file