hyperlit_runtime/
evaluate_directive.rs1use hyperlit_base::result::HyperlitResult;
2use hyperlit_database::Database;
3use hyperlit_model::directive_evaluation::DirectiveEvaluation;
4use hyperlit_model::directives::parse_directive;
5use hyperlit_model::segment::segments_sort_by_title;
6
7pub fn evaluate_directive<'a>(
8 string: &str,
9 database: &'a dyn Database,
10) -> HyperlitResult<DirectiveEvaluation<'a>> {
11 let string = string.trim();
12 let prefix = "§{";
13 Ok(if string.starts_with(prefix) && string.ends_with("}") {
14 let directive = parse_directive(string)?;
15 match directive {
16 hyperlit_model::directives::Directive::IncludeByTag { tag } => {
17 let mut segments = database.get_segments_by_tag(&tag)?;
18 segments_sort_by_title(segments.as_mut_slice());
19 DirectiveEvaluation::Segments { segments }
20 }
21 hyperlit_model::directives::Directive::IncludeRest => {
22 let segments = database.get_all_segments()?;
23 let mut rest_segments: Vec<_> =
24 segments.into_iter().filter(|s| !s.is_included).collect();
25 segments_sort_by_title(rest_segments.as_mut_slice());
26 DirectiveEvaluation::Segments {
27 segments: rest_segments,
28 }
29 }
30 }
31 } else {
32 DirectiveEvaluation::NoDirective
33 })
34}
35
36#[cfg(test)]
37mod tests {
38 use crate::evaluate_directive::evaluate_directive;
39 use hyperlit_base::result::HyperlitResult;
40 use hyperlit_database::Database;
41 use hyperlit_database::in_memory_database::InMemoryDatabase;
42 use hyperlit_model::directive_evaluation::DirectiveEvaluation;
43 use hyperlit_model::location::Location;
44 use hyperlit_model::segment::Segment;
45
46 fn make_segments(how_many: usize) -> Vec<Segment> {
47 vec![Segment::new(0, "title", vec![], "text", Location::new("path", 1)); how_many]
48 }
49
50 #[test]
51 fn test_evaluate_include_rest_directive() -> HyperlitResult<()> {
52 let mut database = InMemoryDatabase::new();
53 database.add_segments(make_segments(3))?;
54 database.set_segment_included(1)?;
55 let evaluation = evaluate_directive("§{@include_rest}", &database)?;
56 match evaluation {
57 DirectiveEvaluation::Segments { segments } => {
58 assert_eq!(
59 segments.iter().map(|s| s.id).collect::<Vec<_>>(),
60 vec![0, 2]
61 );
62 }
63 _ => panic!("should be segments, instead got: {evaluation:?}"),
64 }
65 Ok(())
66 }
67
68 #[test]
69 fn test_evaluate_include_by_tag() -> HyperlitResult<()> {
70 let mut database = InMemoryDatabase::new();
71 database.add_segments(make_segments(3))?;
72 database.add_segments(vec![Segment::new(
73 0,
74 "title A",
75 vec!["the_tag".to_string()],
76 "text",
77 Location::new("path", 1),
78 )])?;
79 database.add_segments(make_segments(3))?;
80 database.add_segments(vec![Segment::new(
81 0,
82 "title B",
83 vec!["the_tag".to_string()],
84 "text",
85 Location::new("path", 1),
86 )])?;
87 let evaluation = evaluate_directive("§{@include_by_tag:#the_tag}", &database)?;
88 match evaluation {
89 DirectiveEvaluation::Segments { segments } => {
90 assert_eq!(
91 segments.iter().map(|s| s.id).collect::<Vec<_>>(),
92 vec![3, 7]
93 );
94 }
95 _ => panic!("should be segments, instead got: {evaluation:?}"),
96 }
97 Ok(())
98 }
99
100 #[test]
101 fn test_evaluate_no_directive() -> HyperlitResult<()> {
102 fn evaluate(string: &str) -> HyperlitResult<()> {
103 let database = InMemoryDatabase::new();
104 let evaluation = evaluate_directive(string, &database)?;
105 match evaluation {
106 DirectiveEvaluation::NoDirective => {
107 }
109 _ => panic!("should be no directive, instead got: {evaluation:?}"),
110 }
111 Ok(())
112 }
113 evaluate("")?;
114 evaluate(" ")?;
115 evaluate("§{ }x")?;
116 evaluate("§{ x")?;
117 evaluate("}")?;
118 evaluate("§ { }")?;
119 Ok(())
120 }
121}