vegafusion_core/spec/transform/
mod.rs1pub mod aggregate;
2pub mod bin;
3pub mod collect;
4pub mod extent;
5pub mod filter;
6pub mod fold;
7pub mod formula;
8pub mod identifier;
9pub mod impute;
10pub mod joinaggregate;
11pub mod lookup;
12pub mod pivot;
13pub mod project;
14pub mod sequence;
15pub mod stack;
16pub mod timeunit;
17pub mod unsupported;
18pub mod window;
19
20use crate::spec::transform::{extent::ExtentTransformSpec, filter::FilterTransformSpec};
21
22use crate::error::Result;
23use crate::expression::column_usage::{ColumnUsage, DatasetsColumnUsage, VlSelectionFields};
24use crate::planning::plan::PlannerConfig;
25use crate::spec::transform::aggregate::AggregateTransformSpec;
26use crate::spec::transform::bin::BinTransformSpec;
27use crate::spec::transform::collect::CollectTransformSpec;
28use crate::spec::transform::fold::FoldTransformSpec;
29use crate::spec::transform::formula::FormulaTransformSpec;
30use crate::spec::transform::identifier::IdentifierTransformSpec;
31use crate::spec::transform::impute::ImputeTransformSpec;
32use crate::spec::transform::joinaggregate::JoinAggregateTransformSpec;
33use crate::spec::transform::lookup::LookupTransformSpec;
34use crate::spec::transform::pivot::PivotTransformSpec;
35use crate::spec::transform::project::ProjectTransformSpec;
36use crate::spec::transform::sequence::SequenceTransformSpec;
37use crate::spec::transform::stack::StackTransformSpec;
38use crate::spec::transform::timeunit::TimeUnitTransformSpec;
39use crate::spec::transform::unsupported::*;
40use crate::spec::transform::window::WindowTransformSpec;
41use crate::task_graph::graph::ScopedVariable;
42use crate::task_graph::scope::TaskScope;
43use crate::task_graph::task::InputVariable;
44use serde::{Deserialize, Serialize};
45use std::ops::Deref;
46
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
48#[serde(tag = "type", rename_all = "lowercase")]
49pub enum TransformSpec {
50 Extent(ExtentTransformSpec),
51 Filter(FilterTransformSpec),
52 Formula(FormulaTransformSpec),
53 Bin(Box<BinTransformSpec>), Aggregate(AggregateTransformSpec),
55 Collect(CollectTransformSpec),
56 Timeunit(TimeUnitTransformSpec),
57 JoinAggregate(JoinAggregateTransformSpec),
58 Window(WindowTransformSpec),
59 Project(ProjectTransformSpec),
60 Stack(StackTransformSpec),
61 Impute(ImputeTransformSpec),
62 Pivot(PivotTransformSpec),
63 Identifier(IdentifierTransformSpec),
64 Fold(FoldTransformSpec),
65 Sequence(SequenceTransformSpec),
66
67 CountPattern(CountpatternTransformSpec),
69 Contour(ContourTransformSpec),
70 Cross(CrossTransformSpec),
71 Crossfilter(CrossfilterTransformSpec),
72 Density(DensityTransformSpec),
73 DotBin(DotbinTransformSpec),
74 Flatten(FlattenTransformSpec),
75 Force(ForceTransformSpec),
76 GeoJson(GeojsonTransformSpec),
77 GeoPath(GeopathTransformSpec),
78 GeoPoint(GeopointTransformSpec),
79 GeoShape(GeoshapeTransformSpec),
80 Graticule(GraticuleTransformSpec),
81 Heatmap(HeatmapTransformSpec),
82 IsoContour(IsocontourTransformSpec),
83 Kde(KdeTransformSpec),
84 Kde2d(Kde2dTransformSpec),
85 Label(LabelTransformSpec),
86 LinkPath(LinkpathTransformSpec),
87 Loess(LoessTransformSpec),
88 Lookup(LookupTransformSpec),
89 Nest(NestTransformSpec),
90 Pack(PackTransformSpec),
91 Partition(PartitionTransformSpec),
92 Pie(PieTransformSpec),
93 Quantile(QuantileTransformSpec),
94 Regression(RegressionTransformSpec),
95 ResolveFilter(ResolvefilterTransformSpec),
96 Sample(SampleTransformSpec),
97 Stratify(StratifyTransformSpec),
98 Tree(TreeTransformSpec),
99 TreeLinks(TreelinksTransformSpec),
100 Treemap(TreemapTransformSpec),
101 Voronoi(VoronoiTransformSpec),
102 WordCloud(WordcloudTransformSpec),
103}
104
105impl Deref for TransformSpec {
106 type Target = dyn TransformSpecTrait;
107
108 fn deref(&self) -> &Self::Target {
109 match self {
110 TransformSpec::Extent(t) => t,
111 TransformSpec::Filter(t) => t,
112 TransformSpec::Formula(t) => t,
113 TransformSpec::Bin(t) => t.as_ref(),
114 TransformSpec::Aggregate(t) => t,
115 TransformSpec::Collect(t) => t,
116 TransformSpec::Timeunit(t) => t,
117 TransformSpec::Project(t) => t,
118 TransformSpec::Stack(t) => t,
119 TransformSpec::Impute(t) => t,
120 TransformSpec::Pivot(t) => t,
121 TransformSpec::Sequence(t) => t,
122
123 TransformSpec::Lookup(t) => t,
125
126 TransformSpec::CountPattern(t) => t,
128 TransformSpec::Contour(t) => t,
129 TransformSpec::Cross(t) => t,
130 TransformSpec::Crossfilter(t) => t,
131 TransformSpec::Density(t) => t,
132 TransformSpec::DotBin(t) => t,
133 TransformSpec::Flatten(t) => t,
134 TransformSpec::Fold(t) => t,
135 TransformSpec::Force(t) => t,
136 TransformSpec::GeoJson(t) => t,
137 TransformSpec::GeoPath(t) => t,
138 TransformSpec::GeoPoint(t) => t,
139 TransformSpec::GeoShape(t) => t,
140 TransformSpec::Graticule(t) => t,
141 TransformSpec::Heatmap(t) => t,
142 TransformSpec::Identifier(t) => t,
143 TransformSpec::IsoContour(t) => t,
144 TransformSpec::JoinAggregate(t) => t,
145 TransformSpec::Kde(t) => t,
146 TransformSpec::Kde2d(t) => t,
147 TransformSpec::Label(t) => t,
148 TransformSpec::LinkPath(t) => t,
149 TransformSpec::Loess(t) => t,
150 TransformSpec::Nest(t) => t,
151 TransformSpec::Pack(t) => t,
152 TransformSpec::Partition(t) => t,
153 TransformSpec::Pie(t) => t,
154 TransformSpec::Quantile(t) => t,
155 TransformSpec::Regression(t) => t,
156 TransformSpec::ResolveFilter(t) => t,
157 TransformSpec::Sample(t) => t,
158 TransformSpec::Stratify(t) => t,
159 TransformSpec::Tree(t) => t,
160 TransformSpec::TreeLinks(t) => t,
161 TransformSpec::Treemap(t) => t,
162 TransformSpec::Voronoi(t) => t,
163 TransformSpec::Window(t) => t,
164 TransformSpec::WordCloud(t) => t,
165 }
166 }
167}
168
169pub trait TransformSpecTrait {
170 fn supported(&self) -> bool {
171 true
172 }
173
174 fn supported_and_allowed(
175 &self,
176 planner_config: &PlannerConfig,
177 task_scope: &TaskScope,
178 scope: &[u32],
179 ) -> bool {
180 let input_vars = self.input_vars().unwrap_or_default();
181 for input_var in &input_vars {
182 if let Ok(resolved) = task_scope.resolve_scope(&input_var.var, scope) {
183 let scoped_var: ScopedVariable = (resolved.var, resolved.scope);
184 if planner_config.client_only_vars.contains(&scoped_var) {
185 return false;
187 }
188 }
189 }
190 self.supported()
191 }
192
193 fn output_signals(&self) -> Vec<String> {
194 Default::default()
195 }
196
197 fn input_vars(&self) -> Result<Vec<InputVariable>> {
198 Ok(Default::default())
199 }
200
201 fn transform_columns(
202 &self,
203 _datum_var: &Option<ScopedVariable>,
204 _usage_scope: &[u32],
205 _task_scope: &TaskScope,
206 _vl_selection_fields: &VlSelectionFields,
207 ) -> TransformColumns {
208 TransformColumns::Unknown
209 }
210
211 fn local_datetime_columns_produced(
212 &self,
213 _input_local_datetime_columns: &[String],
214 ) -> Vec<String> {
215 Vec::new()
216 }
217}
218
219pub enum TransformColumns {
220 PassThrough {
222 usage: DatasetsColumnUsage,
223 produced: ColumnUsage,
224 },
225
226 Overwrite {
228 usage: DatasetsColumnUsage,
229 produced: ColumnUsage,
230 },
231
232 Unknown,
234}