spool/engine/
scenario_matcher.rs1use crate::config::{AppConfig, ProjectConfig};
2use crate::domain::{MatchedModule, MatchedScene, RouteInput};
3
4pub fn match_modules(project: &ProjectConfig, input: &RouteInput) -> Vec<MatchedModule> {
5 project
6 .modules
7 .iter()
8 .filter_map(|module| {
9 let mut reasons = Vec::new();
10 for prefix in &module.path_prefixes {
11 if input.files.iter().any(|file| file.starts_with(prefix)) {
12 reasons.push(format!("file matched path_prefix {prefix}"));
13 }
14 }
15 for keyword in &module.keywords {
16 if input.task.contains(keyword) {
17 reasons.push(format!("task matched keyword {keyword}"));
18 }
19 }
20 if reasons.is_empty() {
21 None
22 } else {
23 Some(MatchedModule {
24 id: module.id.clone(),
25 reasons,
26 })
27 }
28 })
29 .collect()
30}
31
32pub fn match_scenes(config: &AppConfig, input: &RouteInput) -> Vec<MatchedScene> {
33 config
34 .scenes
35 .iter()
36 .filter_map(|scene| {
37 let reasons: Vec<String> = scene
38 .keywords
39 .iter()
40 .filter(|keyword| input.task.contains(keyword.as_str()))
41 .map(|keyword| format!("task matched keyword {keyword}"))
42 .collect();
43 if reasons.is_empty() {
44 None
45 } else {
46 Some(MatchedScene {
47 id: scene.id.clone(),
48 reasons,
49 preferred_notes: scene.preferred_notes.clone(),
50 })
51 }
52 })
53 .collect()
54}