1use std::ops::{Bound, RangeBounds};
2
3use gluex_core::{
4 constants::{MAX_RUN_NUMBER, MIN_RUN_NUMBER},
5 run_periods::RunPeriod,
6 RunNumber,
7};
8
9use crate::conditions::{Expr, IntoExprList};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum RunSelection {
14 All,
16 Runs(Vec<RunNumber>),
18 Range {
20 start: RunNumber,
22 end: RunNumber,
24 },
25}
26
27impl RunSelection {
28 #[must_use]
30 pub fn is_empty(&self) -> bool {
31 matches!(self, RunSelection::Runs(r) if r.is_empty())
32 }
33}
34
35#[derive(Debug, Clone)]
37pub struct RCDBContext {
38 selection: RunSelection,
39 filters: Vec<Expr>,
40}
41
42impl Default for RCDBContext {
43 fn default() -> Self {
44 Self {
45 selection: RunSelection::All,
46 filters: Vec::new(),
47 }
48 }
49}
50
51impl RCDBContext {
52 #[must_use]
54 pub fn new() -> Self {
55 Self::default()
56 }
57
58 #[must_use]
60 pub fn with_run_period(mut self, run_period: RunPeriod) -> Self {
61 self.selection = RunSelection::Range {
62 start: run_period.min_run(),
63 end: run_period.max_run(),
64 };
65 self
66 }
67
68 #[must_use]
70 pub fn with_run(mut self, run: RunNumber) -> Self {
71 self.selection = RunSelection::Runs(vec![run]);
72 self
73 }
74
75 #[must_use]
77 pub fn with_runs(mut self, runs: impl IntoIterator<Item = RunNumber>) -> Self {
78 let mut run_list: Vec<RunNumber> = runs.into_iter().collect();
79 run_list.sort_unstable();
80 run_list.dedup();
81 self.selection = RunSelection::Runs(run_list);
82 self
83 }
84
85 #[must_use]
87 pub fn with_run_range(mut self, run_range: impl RangeBounds<RunNumber>) -> Self {
88 let start = match run_range.start_bound() {
89 Bound::Included(&s) => s,
90 Bound::Excluded(&s) => s.saturating_add(1),
91 Bound::Unbounded => MIN_RUN_NUMBER,
92 };
93 let end = match run_range.end_bound() {
94 Bound::Included(&e) => e,
95 Bound::Excluded(&e) => e.saturating_sub(1),
96 Bound::Unbounded => MAX_RUN_NUMBER,
97 };
98 if start > end {
99 self.selection = RunSelection::Runs(Vec::new());
100 } else {
101 self.selection = RunSelection::Range { start, end };
102 }
103 self
104 }
105
106 #[must_use]
108 pub fn filter(mut self, filters: impl IntoExprList) -> Self {
109 self.filters.extend(filters.into_list());
110 self
111 }
112
113 #[must_use]
115 pub fn selection(&self) -> &RunSelection {
116 &self.selection
117 }
118
119 #[must_use]
121 pub fn runs(&self) -> Option<&[RunNumber]> {
122 if let RunSelection::Runs(runs) = &self.selection {
123 Some(runs)
124 } else {
125 None
126 }
127 }
128
129 #[must_use]
131 pub fn filters(&self) -> &[Expr] {
132 &self.filters
133 }
134}