Setup the loading of the resource manifest file.

This commit is contained in:
Jason Travis Smith 2016-04-08 19:24:46 -04:00
parent 9b9a9a1572
commit d38f5c6291
7 changed files with 464 additions and 1 deletions

12
Cargo.lock generated Normal file
View File

@ -0,0 +1,12 @@
[root]
name = "mason"
version = "0.1.0"
dependencies = [
"scribe 0.1.0 (git+https://gitlab.com/CyberMages/scribe.git)",
]
[[package]]
name = "scribe"
version = "0.1.0"
source = "git+https://gitlab.com/CyberMages/scribe.git#e52418d3bfc28cd1f03cc7f31af06fce2e03f844"

View File

@ -8,4 +8,5 @@ repository = "https://gitlab.com/CyberMages/mason.git"
documentation = ""
keywords = ["mason", "build"]
[dependencies]
[dependencies.scribe]
git = "https://gitlab.com/CyberMages/scribe.git"

85
examples/build.rs Normal file
View File

@ -0,0 +1,85 @@
#[macro_use]
extern crate scribe;
extern crate mason;
use std::path::PathBuf;
use mason::Processor;
pub const RESOURCES_DIR: &'static str = "resources";
pub const MANIFEST_FILENAME: &'static str = "resources.msnr";
pub fn main()
{
let task_count: u64;
let output_dir: PathBuf;
let mut resources_dir: PathBuf;
let mut processor: Processor;
// Get the cargo manifest directory and then append the
// resource directory name to it.
match option_env!("CARGO_MANIFEST_DIR")
{
Some(dir) =>
{
resources_dir = PathBuf::from(dir);
}
None =>
{
resources_dir = PathBuf::new();
}
}
resources_dir.push(RESOURCES_DIR);
// Get the output directory for the build.
match option_env!("OUT_DIR")
{
Some(dir) =>
{
output_dir = PathBuf::from(dir);
}
None =>
{
output_dir = PathBuf::new();
}
}
// Get how many compile tasks should be run at one time.
match option_env!("NUM_JOBS")
{
Some(count) =>
{
match count.parse::<u64>()
{
Ok(val) =>
{
task_count = val;
}
Err(error) =>
{
error!("{}", error);
}
}
}
None =>
{
task_count = 1u64;
}
}
processor = Processor::new();
processor.set_resources_dir(resources_dir.as_path());
processor.set_output_dir(output_dir.as_path());
processor.set_task_count(task_count);
processor.process_manifest_file();
}

4
resources/resources.msnr Normal file
View File

@ -0,0 +1,4 @@
name=test
src=resources.msnr
dst=resources.msnr
compiler=copy

View File

@ -1 +1,12 @@
#[macro_use]
extern crate scribe;
mod loader;
mod processor;
pub use self::loader::{Entry, Loader};
pub use self::processor::Processor;

82
src/loader.rs Normal file
View File

@ -0,0 +1,82 @@
///
pub struct Entry
{
///
name: String,
///
type_hint: String,
///
path: String
}
///
pub struct Loader
{
///
entries: Vec<Entry>
}
impl Entry
{
///
pub fn new(entry_name: String, entry_type: String, entry_path: String)
-> Entry
{
Entry
{
name: entry_name,
type_hint: entry_type,
path: entry_path
}
}
///
pub fn get_name(&self) -> &str
{
self.name.as_str()
}
///
pub fn get_type(&self) -> &str
{
self.type_hint.as_str()
}
///
pub fn get_path(&self) -> &str
{
self.path.as_str()
}
}
impl Loader
{
///
pub fn new() -> Loader
{
Loader
{
entries: Vec::new()
}
}
///
pub fn add_resource_entry(&mut self, name: String,
type_hint: String, path: String)
{
let entry: Entry;
entry = Entry::new(name, type_hint, path);
self.entries.push(entry);
}
///
pub fn get_resource_entries(&self) -> &Vec<Entry>
{
&self.entries
}
}

268
src/processor.rs Normal file
View File

@ -0,0 +1,268 @@
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};
///
const DEFAULT_RESOURCES_DIR: &'static str = "resources";
///
const DEFAULT_MANIFEST_FILENAME: &'static str = "resources.msnr";
///
struct Section
{
///
pub name: String,
///
pub type_hint: String,
///
pub src_path: String,
///
pub dst_path: String,
///
pub compiler: String,
///
pub arguments: String
}
/// Processes the "resources.msnr" file and turns it
/// into a "resources.msnl" file.
pub struct Processor
{
/// The name of the resource manifest file.
manifest_filename: String,
/// The path to the resources directory.
resources_dir: PathBuf,
/// The path to the output directory.
output_dir: PathBuf,
/// The amount of tasks to use when processing the
/// resources from the manifest file.
task_count: u64,
/// The resources sections from the "resources.msnr" file.
sections: Vec<Section>
}
impl Section
{
///
pub fn new() -> Section
{
Section
{
name: String::new(),
type_hint: String::new(),
src_path: String::new(),
dst_path: String::new(),
compiler: String::new(),
arguments: String::new()
}
}
}
impl Processor
{
///
pub fn new() -> Processor
{
Processor
{
manifest_filename: String::from(DEFAULT_MANIFEST_FILENAME),
resources_dir: PathBuf::from(DEFAULT_RESOURCES_DIR),
output_dir: PathBuf::new(),
task_count: 1u64,
sections: Vec::new()
}
}
///
pub fn set_resources_dir(&mut self, dir: &Path)
{
self.resources_dir = PathBuf::from(dir);
println!("Resource dir: {}", self.resources_dir.to_str().unwrap());
}
///
pub fn set_output_dir(&mut self, dir: &Path)
{
self.output_dir = PathBuf::from(dir);
println!("Output dir: {}", self.output_dir.to_str().unwrap());
}
///
pub fn set_task_count(&mut self, count: u64)
{
self.task_count = count;
println!("Task count: {}", self.task_count);
}
///
pub fn process_manifest_file(&mut self)
{
// Read the manifest file from the resources directory.
self.read_manifest_file();
// Compile all the resources from the manifest file.
self.compile_resources();
}
///
///
/// Reading the manifest file can be a blocking
/// operation since there is nothing else to do until
/// the contents of this file have been read.
fn read_manifest_file(&mut self)
{
let file: File;
let mut continue_reading: bool;
let mut line: String;
let mut filepath: PathBuf;
let mut reader: BufReader<File>;
let mut section_buffer: Vec<String>;
// Create the filepath for the resource manifest.
filepath = self.resources_dir.clone();
filepath.push(self.manifest_filename.clone());
// Open the manifest file for reading.
match File::open(filepath)
{
Ok(opened_file) =>
{
file = opened_file
}
Err(error) =>
{
error!("{} -- {:?} {:?}", error,
self.resources_dir, self.manifest_filename);
}
}
// Create a reader to read all of the sections of
// the manifest file.
reader = BufReader::new(file);
// Create a buffer to hold the current
// sections information.
section_buffer = Vec::new();
// Read all of the file line by line.
continue_reading = true;
while continue_reading == true
{
// Read a line from the file.
line = String::new();
match reader.read_line(&mut line)
{
Ok(num_bytes) =>
{
if num_bytes > 0
{
if line == "\n"
{
// This is an empty line so if there are any
// lines in the section buffer then they need
// to be read as a section. If not then there
// is nothing to do.
self.read_manifest_section(&section_buffer);
section_buffer = Vec::new();
}
else
{
// Add this line to the section buffer.
section_buffer.push(line.clone());
}
}
else
{
// It looks like there is nothing more to be read.
continue_reading = false;
}
}
Err(error) =>
{
error!("{}", error);
}
}
}
// Check to make sure that anythin left in
// the section buffer is handled.
self.read_manifest_section(&section_buffer);
}
///
fn read_manifest_section(&mut self, buffer: &Vec<String>)
{
let mut header: &str;
let mut value: &str;
let mut section: Section;
let mut values: Vec<&str>;
if buffer.len() > 0
{
section = Section::new();
for line in buffer.iter()
{
values = line.split("=").collect();
if values.len() == 2
{
header = values[0].trim();
value = values[1].trim();
if header == "name"
{
section.name = String::from(value);
}
else if header == "type"
{
section.type_hint = String::from(value);
}
else if header == "src"
{
section.src_path = String::from(value);
}
else if header == "dst"
{
section.dst_path = String::from(value);
}
else if header == "compiler"
{
section.compiler = String::from(value);
}
else if header == "args"
{
section.arguments = String::from(value);
}
}
else
{
warn!("Detected a name value entry that is incomplete.\n{}",
line.trim());
}
}
self.sections.push(section);
}
}
///
fn compile_resources(&self)
{
}
}