From 17c4de3e5f7e5a5468ad23f421e49e2905b390a8 Mon Sep 17 00:00:00 2001 From: Raamakrishnan Date: Sat, 25 Jan 2020 13:36:34 +0530 Subject: [PATCH] Added logic to parse the entire file --- src/file_parser.rs | 51 +++++++++++++++++++++++ src/lib.rs | 102 ++++----------------------------------------- 2 files changed, 58 insertions(+), 95 deletions(-) create mode 100644 src/file_parser.rs diff --git a/src/file_parser.rs b/src/file_parser.rs new file mode 100644 index 0000000..79024e0 --- /dev/null +++ b/src/file_parser.rs @@ -0,0 +1,51 @@ +use std::collections::HashMap; +use std::error::Error; +use std::fs; + +use crate::line_parser; +use crate::line_parser::LineType; + +#[derive(Debug)] +pub struct Filelist { + pub files: Vec, + pub incdirs: Vec, + pub defines: HashMap, + + pub comments_present: bool, +} + +impl Filelist { + pub fn new() -> Filelist { + Filelist { + files: Vec::new(), + incdirs: Vec::new(), + defines: HashMap::new(), + comments_present: false, + } + } +} + +pub fn parse_file(path: &str) -> Result> { + let contents = fs::read_to_string(path)?; + + let mut filelist = Filelist::new(); + + for line in contents.lines() { + match line_parser::parse_line(line) { + LineType::File(file) => filelist.files.push(file.to_string()), + LineType::Define(define_map) => { + for define in define_map.into_iter() { + filelist.defines.insert(define.0.to_string(), define.1.to_string()); + } + }, + LineType::IncDir(incdirs) => { + for dir in incdirs { + filelist.incdirs.push(dir.to_string()); + } + } + LineType::Comment => filelist.comments_present = true, + _ => {} + } + } + Ok(filelist) +} diff --git a/src/lib.rs b/src/lib.rs index e33bdc4..a093b56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,97 +1,9 @@ -use std::collections::HashMap; +pub mod line_parser; +pub mod file_parser; -#[derive(PartialEq, Debug)] -enum LineType<'a> { - File(&'a str), - IncDir(Vec<&'a str>), - Define(HashMap<&'a str, &'a str>), - Filelist(&'a str), - Comment, - // Unknown, -} - -fn parse_line(line: &str) -> LineType { - let line = line.trim(); - if line.starts_with("-f ") { - let filelist_name = line.trim_start_matches("-f "); - LineType::Filelist(filelist_name) - } else if line.starts_with("+define+") { - // remove +define+ from start and "+" from end - let defines = line.trim_start_matches("+define+").trim_end_matches('+'); - let mut define_map = HashMap::new(); - for define in defines.split('+') { - let split: Vec<&str> = define.splitn(2, '=').collect(); - define_map.insert(split[0], split[1]); - } - LineType::Define(define_map) - } else if line.starts_with("+incdir+") { - // remove +incdir+ from start and "+" from end - let incdirs = line.trim_start_matches("+incdir+").trim_end_matches('+'); - let incdir_vec: Vec<&str> = incdirs.split('+').collect(); - LineType::IncDir(incdir_vec) - } else if line.starts_with("//") { - LineType::Comment - } else { - // Mark everything else as a File - LineType::File(line) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn parse_line_filelist() { - let line = "-f sample/files.f\n"; - assert_eq!(parse_line(line), LineType::Filelist("sample/files.f")); - } - - #[test] - fn parse_line_define_single() { - let line = "+define+CONST1=const1=23\n"; - let mut define_map = HashMap::new(); - define_map.insert("CONST1", "const1=23"); - assert_eq!(parse_line(line), LineType::Define(define_map)); - } - - #[test] - fn parse_line_define_multiple() { - let line = "+define+CONST1=const1+CONST2=const2+CONST3=const3=1+\n"; - let mut define_map = HashMap::new(); - define_map.insert("CONST1", "const1"); - define_map.insert("CONST2", "const2"); - define_map.insert("CONST3", "const3=1"); - assert_eq!(parse_line(line), LineType::Define(define_map)); - } - - #[test] - fn parse_line_incdir_single() { - let line = "+incdir+../sample_dir1/sample_dir2\n"; - let incdir_vec = vec!["../sample_dir1/sample_dir2"]; - assert_eq!(parse_line(line), LineType::IncDir(incdir_vec)); - } - - #[test] - fn parse_line_incdir_multiple() { - let line = "+incdir+../sample_dir1/sample_dir2+../sample_dir2/sample_dir3+sample_dir4/sample_dir5+\n"; - let incdir_vec = vec![ - "../sample_dir1/sample_dir2", - "../sample_dir2/sample_dir3", - "sample_dir4/sample_dir5", - ]; - assert_eq!(parse_line(line), LineType::IncDir(incdir_vec)); - } - - #[test] - fn parse_line_comment() { - let line = "//random_comment"; - assert_eq!(parse_line(line), LineType::Comment); - } - - #[test] - fn parse_line_file() { - let line = "any_random_line_is_a_file"; - assert_eq!(parse_line(line), LineType::File("any_random_line_is_a_file")); - } +use file_parser::Filelist; +use std::error::Error; + +pub fn parse(path: &str) -> Result> { + file_parser::parse_file(path) }