1use crate::{
2 models::Currency,
3 parser::{ParsedLedger, Rule, Tokenizer},
4 CommonOpts, List,
5};
6use glob::glob;
7use pest::iterators::Pair;
8
9use std::{convert::TryFrom, path::PathBuf};
10
11impl<'a> Tokenizer<'a> {
12 pub fn include(
17 &self,
18 element: Pair<Rule>,
19 options: &CommonOpts,
20 commodities: &List<Currency>,
21 ) -> Result<ParsedLedger, Box<dyn std::error::Error>> {
22 let mut pattern = String::new();
23 let mut files: Vec<PathBuf> = Vec::new();
24 if let Some(current_path) = self.file {
25 let mut parent = current_path.parent().unwrap().to_str().unwrap().to_string();
26 if parent.is_empty() {
27 parent.push('.')
28 }
29 parent.push('/');
30 pattern.push_str(parent.as_str());
31 }
32 let parsed_glob = element.into_inner().next().unwrap().as_str();
33 pattern.push_str(parsed_glob);
34 for entry in glob(&pattern).expect("Failed to read glob pattern") {
35 match entry {
36 Ok(path) => {
37 files.push(path.clone());
38 if self.seen_files.get(&path).is_some() {
39 panic!("Cycle detected. {:?}", &path);
40 }
41 }
42 Err(e) => eprintln!("{:?}", e),
43 }
44 }
45 let mut items: ParsedLedger = ParsedLedger::new();
46 for file in files {
47 let mut inner_tokenizer: Tokenizer = Tokenizer::try_from(&file)?;
48 for p in self.seen_files.iter() {
49 inner_tokenizer.seen_files.insert(*p);
50 }
51 let mut new_items: ParsedLedger =
52 inner_tokenizer.tokenize_with_currencies(options, Some(commodities));
53 items.append(&mut new_items);
54 }
55 Ok(items)
56 }
57}