1#[derive(Debug, Clone, PartialEq, Eq)]
3pub struct Span {
4 pub start: usize,
5 pub end: usize,
6}
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct Spanned<T> {
11 pub node: T,
12 pub span: Span,
13}
14
15#[derive(Debug, Clone, PartialEq)]
17pub struct File {
18 pub statements: Vec<Spanned<Statement>>,
19}
20
21#[derive(Debug, Clone, PartialEq)]
23pub enum Statement {
24 Timeline(TimelineBlock),
25 Lane(LaneDecl),
26 Group(GroupDecl),
27 Span(SpanDecl),
28 Event(EventDecl),
29 EventRange(EventRangeDecl),
30 Import(ImportBlock),
31 Map(MapBlock),
32 Template(TemplateBlock),
33 Apply(ApplyBlock),
34}
35
36#[derive(Debug, Clone, PartialEq)]
40pub struct TimelineBlock {
41 pub name: String,
42 pub title: Option<String>,
43 pub unit: Option<String>,
44 pub range: Option<RangeExpr>,
45 pub calendar: Option<String>,
46 pub color_map: Vec<(String, String)>,
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum TimeValue {
57 Year(i64),
58 YearMonth(i64, u8),
59 Date(i64, u8, u8),
60}
61
62impl TimeValue {
63 pub fn year(&self) -> i64 {
65 match self {
66 TimeValue::Year(y) => *y,
67 TimeValue::YearMonth(y, _) => *y,
68 TimeValue::Date(y, _, _) => *y,
69 }
70 }
71
72 pub fn month(&self) -> Option<u8> {
73 match self {
74 TimeValue::Year(_) => None,
75 TimeValue::YearMonth(_, m) => Some(*m),
76 TimeValue::Date(_, m, _) => Some(*m),
77 }
78 }
79
80 pub fn day(&self) -> Option<u8> {
81 match self {
82 TimeValue::Year(_) | TimeValue::YearMonth(_, _) => None,
83 TimeValue::Date(_, _, d) => Some(*d),
84 }
85 }
86
87 pub fn to_sortable(&self) -> (i64, u8, u8) {
91 match self {
92 TimeValue::Year(y) => (*y, 0, 0),
93 TimeValue::YearMonth(y, m) => (*y, *m, 0),
94 TimeValue::Date(y, m, d) => (*y, *m, *d),
95 }
96 }
97}
98
99impl std::fmt::Display for TimeValue {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 match self {
102 TimeValue::Year(y) => write!(f, "{y}"),
103 TimeValue::YearMonth(y, m) => write!(f, "{y:04}-{m:02}"),
104 TimeValue::Date(y, m, d) => write!(f, "{y:04}-{m:02}-{d:02}"),
105 }
106 }
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq)]
111pub struct RangeExpr {
112 pub start: TimeValue,
113 pub end: TimeValue,
114}
115
116#[derive(Debug, Clone, PartialEq)]
120pub struct LaneDecl {
121 pub label: String,
122 pub alias: Option<String>,
123 pub kind: Option<String>,
124 pub order: Option<i64>,
125}
126
127#[derive(Debug, Clone, PartialEq)]
129pub struct GroupDecl {
130 pub label: String,
131 pub lanes: Vec<LaneDecl>,
132}
133
134#[derive(Debug, Clone, PartialEq)]
138pub struct SpanDecl {
139 pub lane_ref: String,
140 pub start: TimeValue,
141 pub end: TimeValue,
142 pub label: String,
143 pub props: ItemProps,
144}
145
146#[derive(Debug, Clone, PartialEq)]
148pub struct EventDecl {
149 pub lane_ref: String,
150 pub time: TimeValue,
151 pub label: String,
152 pub props: ItemProps,
153}
154
155#[derive(Debug, Clone, PartialEq)]
157pub struct EventRangeDecl {
158 pub lane_ref: String,
159 pub start: TimeValue,
160 pub end: TimeValue,
161 pub label: String,
162 pub props: ItemProps,
163}
164
165#[derive(Debug, Clone, PartialEq, Default)]
167pub struct ItemProps {
168 pub tags: Vec<String>,
169 pub source: Option<SourceRef>,
170 pub id: Option<String>,
171 pub origin: Option<String>,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct SourceRef {
177 pub prefix: String,
178 pub qid: String,
179}
180
181#[derive(Debug, Clone, PartialEq)]
185pub struct ImportBlock {
186 pub source_type: String,
187 pub alias: Option<String>,
188 pub items: Vec<ImportItem>,
189 pub policy: Option<ReimportPolicy>,
190}
191
192#[derive(Debug, Clone, PartialEq)]
194pub enum ImportItem {
195 Entity { qid: String, alias: Option<String> },
197 Query {
199 query: String,
200 alias: Option<String>,
201 },
202}
203
204#[derive(Debug, Clone, Copy, PartialEq, Eq)]
206pub enum FieldStrategy {
207 Manual,
209 Wikidata,
211 Merge,
213}
214
215#[derive(Debug, Clone, Copy, PartialEq, Eq)]
217pub struct FieldPriorityConfig {
218 pub label: FieldStrategy,
219 pub time: FieldStrategy,
220 pub tags: FieldStrategy,
221}
222
223impl Default for FieldPriorityConfig {
224 fn default() -> Self {
225 Self {
226 label: FieldStrategy::Manual,
227 time: FieldStrategy::Wikidata,
228 tags: FieldStrategy::Merge,
229 }
230 }
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
234pub enum ReimportPolicy {
235 MergeBySource,
236 OverwriteImported,
237 KeepManual,
238 FieldPriority(FieldPriorityConfig),
239}
240
241#[derive(Debug, Clone, PartialEq)]
245pub struct TemplateBlock {
246 pub name: String,
247 pub alias: Option<String>,
248 pub target_type: MapTargetType,
249 pub props: Vec<MapProp>,
250}
251
252#[derive(Debug, Clone, PartialEq)]
254pub struct ApplyBlock {
255 pub template_alias: String,
256 pub import_alias: String,
257 pub overrides: Vec<MapProp>,
259}
260
261#[derive(Debug, Clone, Copy, PartialEq, Eq)]
264pub enum MapTargetType {
265 Span,
266 Event,
267 EventRange,
268}
269
270#[derive(Debug, Clone, PartialEq)]
271pub struct MapBlock {
272 pub source_ref: String,
273 pub target_type: MapTargetType,
274 pub props: Vec<MapProp>,
275}
276
277#[derive(Debug, Clone, PartialEq)]
278pub enum MapProp {
279 Lane(String),
280 Start(MapExpr),
281 End(MapExpr),
282 Time(MapExpr),
283 Label(LabelExpr),
284 Tags(Vec<String>),
285 Filter(FilterExpr),
286 Expand(ClaimCall),
288}
289
290#[derive(Debug, Clone, PartialEq)]
291pub struct MapExpr {
292 pub fallbacks: Vec<MapFallback>,
293}
294
295#[derive(Debug, Clone, PartialEq)]
297pub enum MapFallback {
298 Claim(ClaimExpr),
299 Literal(i64),
300}
301
302#[derive(Debug, Clone, PartialEq)]
303pub struct ClaimExpr {
304 pub claim: ClaimCall,
305 pub qualifier: Option<String>,
308 pub accessor: Option<String>,
309 pub offset: Option<i32>,
311}
312
313#[derive(Debug, Clone, PartialEq, Eq)]
314pub struct ClaimCall {
315 pub property: String,
316}
317
318#[derive(Debug, Clone, PartialEq)]
319pub struct LabelExpr {
320 pub fallbacks: Vec<LabelRef>,
321}
322
323#[derive(Debug, Clone, PartialEq, Eq)]
324pub struct LabelRef {
325 pub lang: String,
326}
327
328#[derive(Debug, Clone, PartialEq)]
331pub enum FilterExpr {
332 And(Box<FilterExpr>, Box<FilterExpr>),
333 Or(Box<FilterExpr>, Box<FilterExpr>),
334 Not(Box<FilterExpr>),
335 Compare {
336 lhs: FilterOperand,
337 op: CompareOp,
338 rhs: FilterOperand,
339 },
340 StringMatch {
341 lhs: LabelRef,
342 op: StringMatchOp,
343 rhs: String,
344 },
345}
346
347#[derive(Debug, Clone, Copy, PartialEq, Eq)]
348pub enum CompareOp {
349 Eq,
350 NotEq,
351 Lt,
352 Le,
353 Gt,
354 Ge,
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq)]
358pub enum StringMatchOp {
359 Contains,
360 StartsWith,
361}
362
363#[derive(Debug, Clone, PartialEq)]
364pub enum FilterOperand {
365 Claim(ClaimExpr),
366 Int(i64),
367 Null,
368}