1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#![allow(non_snake_case)]
mod attr;
mod metadata;
mod error;
mod ext;
mod syndecode;
use std::fs;
use std::path::Path;
use syn::{DeriveInput, Item};
use ignore::Walk;
use syndecode::Attributes;
pub use metadata::*;
pub use attr::*;
pub use error::*;
pub use ext::*;
#[derive(Default, Debug)]
pub struct LoadOptions {
pub verbose: bool,
}
pub fn load_from_project(paths: &[&Path], opts: &LoadOptions) -> anyhow::Result<Vec<TableMetadata>> {
let walk = paths.iter().flat_map(Walk::new);
let mut results = vec![];
let walk = walk.filter_map(|e| e.ok())
.filter(|e| e.path().extension().map(|e| e == "rs")
.unwrap_or(false));
for entry in walk {
let contents = fs::read_to_string(entry.path())?;
if !contents.contains("Model") {
continue;
}
if opts.verbose {
eprintln!("{}: Checking for #[derive(Model)]", entry.path().display());
}
let ast = syn::parse_file(&contents)?;
let structs = ast.items.into_iter().filter_map(|item| match item {
Item::Struct(s) => Some(s),
_ => None,
})
.map(|s| {
let attrs = Attributes::filter_from(&s.attrs, "ormlite");
(s, attrs)
})
.inspect(|(s, attrs)| {
if opts.verbose {
eprintln!("{}: Found struct {}. Detected derives: {:?}", entry.path().display(), s.ident, attrs.derives());
}
})
.filter(|(_, attrs)| attrs.has_derive("Model"))
.collect::<Vec<_>>();
for (item, _attrs) in structs {
let derive: DeriveInput = item.into();
let table = TableMetadata::try_from(&derive)
.map_err(|e| SyndecodeError(format!(
"{}: Encounterd an error while scanning for #[derive(Model)] structs: {}",
entry.path().display(), e))
)?;
results.push(table);
}
}
if results.is_empty() {
panic!("No models found in the given paths: {}", paths.iter().map(|p| p.display().to_string()).collect::<Vec<_>>().join(", "));
}
Ok(results)
}