#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Span {
pub start: usize,
pub end: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Spanned<T> {
pub node: T,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq)]
pub struct File {
pub statements: Vec<Spanned<Statement>>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Statement {
Timeline(TimelineBlock),
Lane(LaneDecl),
Group(GroupDecl),
Span(SpanDecl),
Event(EventDecl),
EventRange(EventRangeDecl),
Import(ImportBlock),
Map(MapBlock),
Template(TemplateBlock),
Apply(ApplyBlock),
}
#[derive(Debug, Clone, PartialEq)]
pub struct TimelineBlock {
pub name: String,
pub title: Option<String>,
pub unit: Option<String>,
pub range: Option<RangeExpr>,
pub calendar: Option<String>,
pub color_map: Vec<(String, String)>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TimeValue {
Year(i64),
YearMonth(i64, u8),
Date(i64, u8, u8),
}
impl TimeValue {
pub fn year(&self) -> i64 {
match self {
TimeValue::Year(y) => *y,
TimeValue::YearMonth(y, _) => *y,
TimeValue::Date(y, _, _) => *y,
}
}
pub fn month(&self) -> Option<u8> {
match self {
TimeValue::Year(_) => None,
TimeValue::YearMonth(_, m) => Some(*m),
TimeValue::Date(_, m, _) => Some(*m),
}
}
pub fn day(&self) -> Option<u8> {
match self {
TimeValue::Year(_) | TimeValue::YearMonth(_, _) => None,
TimeValue::Date(_, _, d) => Some(*d),
}
}
pub fn to_sortable(&self) -> (i64, u8, u8) {
match self {
TimeValue::Year(y) => (*y, 0, 0),
TimeValue::YearMonth(y, m) => (*y, *m, 0),
TimeValue::Date(y, m, d) => (*y, *m, *d),
}
}
}
impl std::fmt::Display for TimeValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
TimeValue::Year(y) => write!(f, "{y}"),
TimeValue::YearMonth(y, m) => write!(f, "{y:04}-{m:02}"),
TimeValue::Date(y, m, d) => write!(f, "{y:04}-{m:02}-{d:02}"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RangeExpr {
pub start: TimeValue,
pub end: TimeValue,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LaneDecl {
pub label: String,
pub alias: Option<String>,
pub kind: Option<String>,
pub order: Option<i64>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GroupDecl {
pub label: String,
pub lanes: Vec<LaneDecl>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct SpanDecl {
pub lane_ref: String,
pub start: TimeValue,
pub end: TimeValue,
pub label: String,
pub props: ItemProps,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EventDecl {
pub lane_ref: String,
pub time: TimeValue,
pub label: String,
pub props: ItemProps,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EventRangeDecl {
pub lane_ref: String,
pub start: TimeValue,
pub end: TimeValue,
pub label: String,
pub props: ItemProps,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct ItemProps {
pub tags: Vec<String>,
pub source: Option<SourceRef>,
pub id: Option<String>,
pub origin: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SourceRef {
pub prefix: String,
pub qid: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ImportBlock {
pub source_type: String,
pub alias: Option<String>,
pub items: Vec<ImportItem>,
pub policy: Option<ReimportPolicy>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ImportItem {
Entity { qid: String, alias: Option<String> },
Query {
query: String,
alias: Option<String>,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FieldStrategy {
Manual,
Wikidata,
Merge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct FieldPriorityConfig {
pub label: FieldStrategy,
pub time: FieldStrategy,
pub tags: FieldStrategy,
}
impl Default for FieldPriorityConfig {
fn default() -> Self {
Self {
label: FieldStrategy::Manual,
time: FieldStrategy::Wikidata,
tags: FieldStrategy::Merge,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReimportPolicy {
MergeBySource,
OverwriteImported,
KeepManual,
FieldPriority(FieldPriorityConfig),
}
#[derive(Debug, Clone, PartialEq)]
pub struct TemplateBlock {
pub name: String,
pub alias: Option<String>,
pub target_type: MapTargetType,
pub props: Vec<MapProp>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct ApplyBlock {
pub template_alias: String,
pub import_alias: String,
pub overrides: Vec<MapProp>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MapTargetType {
Span,
Event,
EventRange,
}
#[derive(Debug, Clone, PartialEq)]
pub struct MapBlock {
pub source_ref: String,
pub target_type: MapTargetType,
pub props: Vec<MapProp>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum MapProp {
Lane(String),
Start(MapExpr),
End(MapExpr),
Time(MapExpr),
Label(LabelExpr),
Tags(Vec<String>),
Filter(FilterExpr),
Expand(ClaimCall),
}
#[derive(Debug, Clone, PartialEq)]
pub struct MapExpr {
pub fallbacks: Vec<MapFallback>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum MapFallback {
Claim(ClaimExpr),
Literal(i64),
}
#[derive(Debug, Clone, PartialEq)]
pub struct ClaimExpr {
pub claim: ClaimCall,
pub qualifier: Option<String>,
pub accessor: Option<String>,
pub offset: Option<i32>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ClaimCall {
pub property: String,
}
#[derive(Debug, Clone, PartialEq)]
pub struct LabelExpr {
pub fallbacks: Vec<LabelRef>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LabelRef {
pub lang: String,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FilterExpr {
And(Box<FilterExpr>, Box<FilterExpr>),
Or(Box<FilterExpr>, Box<FilterExpr>),
Not(Box<FilterExpr>),
Compare {
lhs: FilterOperand,
op: CompareOp,
rhs: FilterOperand,
},
StringMatch {
lhs: LabelRef,
op: StringMatchOp,
rhs: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompareOp {
Eq,
NotEq,
Lt,
Le,
Gt,
Ge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StringMatchOp {
Contains,
StartsWith,
}
#[derive(Debug, Clone, PartialEq)]
pub enum FilterOperand {
Claim(ClaimExpr),
Int(i64),
Null,
}