diff --git a/src/main.rs b/src/main.rs index adea96b..bc9fde4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,10 @@ +use slug::slugify; use std::env; -use xml::{Event, Parser}; use std::fs::File; use std::io::prelude::*; use std::path::Path; use std::vec::Vec; -use slug::slugify; -use base64::decode; +use xml::{Event, Parser}; #[derive(Debug)] enum CurrentTag { @@ -14,7 +13,7 @@ enum CurrentTag { Resource, ResourceData, ResourceAttributes, - ResourceAttributesFilename + ResourceAttributesFilename, } #[derive(Debug)] @@ -22,42 +21,69 @@ struct State { tag: Option, title: Option, filename: Option, - data: Vec + data: Vec, + content: Vec, } impl State { pub fn new() -> Self { - Self { tag: None, title: None, filename: None, data: Vec::new() } + Self { + tag: None, + title: None, + filename: None, + data: Vec::new(), + content: Vec::new(), + } } - pub fn with_title(self, title:String) -> Self { - Self { title: Some(title.to_string()), - ..self } + pub fn with_title(self, title: String) -> Self { + Self { + title: Some(title.to_string()), + ..self + } } pub fn with_filename(self, filename: String) -> Self { - Self { filename: Some(filename), - ..self } + Self { + filename: Some(filename), + ..self + } + } + + pub fn with_tag(self, tag: CurrentTag) -> Self { + Self { + tag: Some(tag), + ..self + } } - pub fn with_tag(self, tag:CurrentTag) -> Self { - Self { tag: Some(tag), - ..self } + pub fn with_data(self, data: Vec) -> Self { + Self { data: data, ..self } } - pub fn with_data(self, data:Vec) -> Self { - Self { data: data, - ..self } + pub fn with_content(self, content: Vec) -> Self { + Self { + content: content, + ..self + } } pub fn remove_tag(self) -> Self { - Self { tag: None, - ..self } + Self { tag: None, ..self } } pub fn remove_data(self) -> Self { - Self { data: Vec::new(), - ..self } + Self { + data: Vec::new(), + ..self + } + } + + pub fn remove_content(self) -> Self { + Self { + content: Vec::new(), + ..self + } } } @@ -76,7 +102,7 @@ fn open_tag(current_state: State, tag: &str) -> State { "resource-attributes" => current_state.with_tag(CurrentTag::ResourceAttributes), "file-name" => current_state.with_tag(CurrentTag::ResourceAttributesFilename), "note" => State::new(), - _ => current_state + _ => current_state, } } @@ -93,59 +119,73 @@ fn dump_resource(current_state: &State) -> () { target.write_all(&content).unwrap(); } +fn dump_note_contents(current_state: &State) -> () { + let filename = Path::new("data") + .join(current_state.title.as_ref().unwrap()) + .join("content.md"); + let mut target = File::create(filename).unwrap(); + target.write_all(¤t_state.content).unwrap(); +} + fn close_tag(current_state: State, tag: &str) -> State { match tag { "resource" => { dump_resource(¤t_state); current_state.remove_data() }, - _ => current_state.remove_tag() + "content" => { + dump_note_contents(¤t_state); + current_state.remove_content() + }, + _ => current_state.remove_tag(), } } fn main() { - let args:Vec<_> = env::args().collect(); + let args: Vec<_> = env::args().collect(); if args.len() != 2 { println!("Required: filename."); std::process::exit(2); } - + let filename = &args[1]; - + println!("Will process {}", filename); - + // Need to find a way to load small chunks and feed it to the parser while parsing. // (E.g., load 1024 bytes, feed it to the parser and, if the parser can't continue, // feed more data, till the end of file). let mut file = File::open(filename).unwrap(); let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); - + let mut parser = Parser::new(); parser.feed_str(&contents); - - parser.fold(State::new(), {|state:State, element| { - println!("State: {:?}", state); - - match element.unwrap() { - Event::ElementStart(tag) => open_tag(state, tag.name.as_ref()), - Event::ElementEnd(tag) => close_tag(state, tag.name.as_ref()), - Event::Characters(data) => { - match state.tag { - Some(CurrentTag::Title) => state.with_title(create_note_storage(&data)), - Some(CurrentTag::ResourceData) => state.with_data( - data - .into_bytes() - .iter() - .filter(|&x| *x != 13 && *x != 10) // remove new lines, it is base 64, after all - .map(|&x| x) - .collect() - ), - Some(CurrentTag::ResourceAttributesFilename) => state.with_filename(data), - _ => state + + parser.fold(State::new(), { + |state: State, element| { + println!("State: {:?}", state); + + match element.unwrap() { + Event::ElementStart(tag) => open_tag(state, tag.name.as_ref()), + Event::ElementEnd(tag) => close_tag(state, tag.name.as_ref()), + Event::Characters(data) => { + match state.tag { + Some(CurrentTag::Title) => state.with_title(create_note_storage(&data)), + Some(CurrentTag::ResourceData) => state.with_data( + data.into_bytes() + .iter() + .filter(|&x| *x != 13 && *x != 10) // remove new lines, it is base 64, after all + .map(|&x| x) + .collect(), + ), + Some(CurrentTag::Content) => state.with_content(data.into_bytes()), + Some(CurrentTag::ResourceAttributesFilename) => state.with_filename(data), + _ => state, + } } - }, - _ => state + _ => state, + } } - }}); + }); }