es_fluent_sc_parser/
lib.rs1use crate::visitor::FtlVisitor;
2use std::fs;
3use std::path::{Path, PathBuf};
4use walkdir::WalkDir;
5
6pub mod error;
7mod processor;
8mod visitor;
9
10use error::FluentScParserError;
11use es_fluent_core::registry::FtlTypeInfo;
12
13pub fn parse_directory(dir_path: &Path) -> Result<Vec<FtlTypeInfo>, FluentScParserError> {
14 log::info!(
15 "Starting FTL type info parsing in directory: {}",
16 dir_path.display()
17 );
18
19 let rust_files: Vec<PathBuf> = WalkDir::new(dir_path)
20 .into_iter()
21 .filter_map(|entry_result| match entry_result {
22 Ok(entry) => {
23 let path = entry.path();
24 if path.is_file()
25 && let Some(ext) = path.extension()
26 && ext == "rs"
27 {
28 Some(Ok(path.to_path_buf()))
29 } else {
30 None
31 }
32 },
33 Err(e) => Some(Err(FluentScParserError::WalkDir(dir_path.to_path_buf(), e))),
34 })
35 .collect::<Result<Vec<_>, _>>()?;
36
37 log::debug!("Found {} Rust files to parse.", rust_files.len());
38
39 let file_results: Result<Vec<Vec<FtlTypeInfo>>, FluentScParserError> = rust_files
40 .iter()
41 .map(|file_path| {
42 log::trace!("Parsing file: {}", file_path.display());
43 let content = fs::read_to_string(file_path)
44 .map_err(|e| FluentScParserError::Io(file_path.clone(), e))?;
45 let syntax_tree = syn::parse_file(&content)
46 .map_err(|e| FluentScParserError::Syn(file_path.clone(), e))?;
47
48 let mut visitor = FtlVisitor::new(file_path);
49 syn::visit::visit_file(&mut visitor, &syntax_tree);
50 Ok(visitor.type_infos().to_owned())
51 })
52 .collect();
53
54 let results: Vec<FtlTypeInfo> = file_results?
55 .into_iter()
56 .filter(|type_infos| !type_infos.is_empty())
57 .flatten()
58 .collect::<std::collections::HashSet<_>>()
59 .into_iter()
60 .collect();
61
62 log::info!(
63 "Finished parsing. Found {} FTL type info entries.",
64 results.len()
65 );
66 Ok(results)
67}