1use std::convert::Infallible;
13
14use super::column::CompatColumnMap;
15use super::private::{CellAccessor, Column, ColumnSerialize, LabelMap, Table};
16use super::util::CompatIter;
17use crate::legacy::{LegacyColumn, LegacyFlag, LegacyRow, LegacyTable};
18use crate::modern::{ModernColumn, ModernRow, ModernTable};
19use crate::{BdatResult, Cell, Label, RowId, RowRef, ValueType};
20
21#[derive(Debug, Clone, PartialEq)]
55pub enum CompatTable<'b> {
56 Modern(ModernTable<'b>),
57 Legacy(LegacyTable<'b>),
58}
59
60pub enum CompatRow<'buf> {
62 Modern(ModernRow<'buf>),
63 Legacy(LegacyRow<'buf>),
64}
65
66#[derive(Clone, Copy)]
68pub enum CompatRef<'t, 'buf> {
69 Modern(&'t ModernRow<'buf>),
70 Legacy(&'t LegacyRow<'buf>),
71}
72
73#[derive(Clone, PartialEq, Eq)]
75pub enum CompatColumn<'buf> {
76 Modern(ModernColumn<'buf>),
77 Legacy(LegacyColumn<'buf>),
78}
79
80#[derive(Clone, Copy)]
82pub enum CompatColumnRef<'t, 'buf> {
83 Modern(&'t ModernColumn<'buf>),
84 Legacy(&'t LegacyColumn<'buf>),
85}
86
87pub type CompatRowRef<'t, 'buf> = RowRef<CompatRef<'t, 'buf>, CompatColumnMap<'t, 'buf>>;
89
90macro_rules! versioned {
91 ($var:expr, $name:ident) => {
92 match $var {
93 Self::Modern(m) => &m.$name,
94 Self::Legacy(l) => &l.$name,
95 }
96 };
97 ($var:expr, $name:ident($($par:expr ) *)) => {
98 match $var {
99 Self::Modern(m) => m . $name ( $($par, )* ),
100 Self::Legacy(l) => l . $name ( $($par, )* ),
101 }
102 };
103}
104
105impl<'b> CompatTable<'b> {
106 pub fn as_modern(&self) -> &ModernTable<'b> {
111 match self {
112 Self::Modern(m) => m,
113 _ => panic!("not modern"),
114 }
115 }
116
117 pub fn as_legacy(&self) -> &LegacyTable<'b> {
122 match self {
123 Self::Legacy(l) => l,
124 _ => panic!("not legacy"),
125 }
126 }
127
128 pub fn as_modern_mut(&mut self) -> &mut ModernTable<'b> {
133 match self {
134 Self::Modern(m) => m,
135 _ => panic!("not modern"),
136 }
137 }
138
139 pub fn as_legacy_mut(&mut self) -> &mut LegacyTable<'b> {
144 match self {
145 Self::Legacy(l) => l,
146 _ => panic!("not legacy"),
147 }
148 }
149
150 pub fn into_modern(self) -> ModernTable<'b> {
158 match self {
159 Self::Modern(m) => m,
160 _ => panic!("not modern"),
161 }
162 }
163
164 pub fn into_legacy(self) -> LegacyTable<'b> {
172 match self {
173 Self::Legacy(l) => l,
174 _ => panic!("not legacy"),
175 }
176 }
177
178 pub fn is_modern(&self) -> bool {
180 matches!(self, Self::Modern(_))
181 }
182
183 pub fn is_legacy(&self) -> bool {
185 matches!(self, Self::Legacy(_))
186 }
187
188 pub fn try_into_modern(self) -> BdatResult<ModernTable<'b>> {
194 match self {
195 Self::Modern(m) => Ok(m),
196 Self::Legacy(l) => Ok(l.try_into()?),
197 }
198 }
199
200 pub fn try_into_legacy(self) -> BdatResult<LegacyTable<'b>> {
206 match self {
207 Self::Modern(m) => Ok(m.try_into()?),
208 Self::Legacy(l) => Ok(l),
209 }
210 }
211
212 pub fn name(&self) -> Label {
215 match self {
216 Self::Modern(m) => m.name().as_ref(),
217 Self::Legacy(l) => l.name().into(),
218 }
219 }
220
221 pub(crate) fn name_cloned(&self) -> Label<'b> {
222 match self {
223 Self::Modern(m) => m.name.clone(),
224 Self::Legacy(l) => l.name.clone().into(),
225 }
226 }
227
228 pub fn set_name(&mut self, name: Label<'b>) {
234 match self {
235 Self::Modern(m) => m.set_name(name),
236 Self::Legacy(l) => {
237 l.set_name(name.try_into().expect("hashed labels are not supported"))
238 }
239 }
240 }
241
242 pub fn base_id(&self) -> RowId {
244 match self {
245 Self::Modern(m) => m.base_id(),
246 Self::Legacy(l) => l.base_id() as u32,
247 }
248 }
249
250 pub fn row(&self, id: RowId) -> CompatRowRef<'_, 'b> {
259 match self {
260 Self::Modern(m) => m
261 .row(id)
262 .map(CompatRef::Modern, CompatColumnMap::Modern(&m.columns)),
263 Self::Legacy(l) => l
264 .row(id.try_into().expect("invalid id for legacy row"))
265 .map(CompatRef::Legacy, CompatColumnMap::Legacy(&l.columns)),
266 }
267 }
268
269 pub fn get_row(&self, id: RowId) -> Option<CompatRowRef<'_, 'b>> {
276 match self {
277 Self::Modern(m) => m
278 .get_row(id)
279 .map(|r| r.map(CompatRef::Modern, CompatColumnMap::Modern(&m.columns))),
280 Self::Legacy(l) => id
281 .try_into()
282 .ok()
283 .and_then(|id| l.get_row(id))
284 .map(|r| r.map(CompatRef::Legacy, CompatColumnMap::Legacy(&l.columns))),
285 }
286 }
287
288 pub fn rows(&self) -> impl Iterator<Item = CompatRowRef<'_, 'b>> {
290 match self {
291 Self::Modern(m) => CompatIter::Modern(
292 m.rows()
293 .map(|r| r.map(CompatRef::Modern, CompatColumnMap::Modern(&m.columns))),
294 ),
295 Self::Legacy(l) => CompatIter::Legacy(
296 l.rows()
297 .map(|r| r.map(CompatRef::Legacy, CompatColumnMap::Legacy(&l.columns))),
298 ),
299 }
300 }
301
302 pub fn into_rows(self) -> impl Iterator<Item = CompatRow<'b>> {
304 match self {
305 Self::Modern(m) => CompatIter::Modern(m.into_rows().map(CompatRow::Modern)),
306 Self::Legacy(l) => CompatIter::Legacy(l.into_rows().map(CompatRow::Legacy)),
307 }
308 }
309
310 pub fn into_rows_id(self) -> impl Iterator<Item = (u32, CompatRow<'b>)> {
313 match self {
314 Self::Modern(m) => {
315 CompatIter::Modern(m.into_rows_id().map(|(id, r)| (id, CompatRow::Modern(r))))
316 }
317 Self::Legacy(l) => CompatIter::Legacy(
318 l.into_rows_id()
319 .map(|(id, r)| (id as u32, CompatRow::Legacy(r))),
320 ),
321 }
322 }
323
324 pub fn columns(&self) -> impl Iterator<Item = CompatColumnRef<'_, 'b>> {
326 match self {
327 Self::Modern(m) => CompatIter::Modern(m.columns().map(CompatColumnRef::Modern)),
328 Self::Legacy(l) => CompatIter::Legacy(l.columns().map(CompatColumnRef::Legacy)),
329 }
330 }
331
332 pub fn into_columns(self) -> impl Iterator<Item = CompatColumn<'b>> {
337 match self {
338 Self::Modern(m) => CompatIter::Modern(m.into_columns().map(CompatColumn::Modern)),
339 Self::Legacy(l) => CompatIter::Legacy(l.into_columns().map(CompatColumn::Legacy)),
340 }
341 }
342
343 pub fn row_count(&self) -> usize {
344 versioned!(&self, row_count())
345 }
346
347 pub fn column_count(&self) -> usize {
348 versioned!(&self, column_count())
349 }
350}
351
352impl<'b> CompatColumn<'b> {
353 pub fn as_ref(&self) -> CompatColumnRef<'_, 'b> {
354 match self {
355 CompatColumn::Modern(m) => CompatColumnRef::Modern(m),
356 CompatColumn::Legacy(l) => CompatColumnRef::Legacy(l),
357 }
358 }
359}
360
361impl<'buf> CompatColumn<'buf> {
362 pub fn label(&self) -> Label {
365 match self {
366 Self::Modern(m) => m.label().as_ref(),
367 Self::Legacy(l) => l.label().into(),
368 }
369 }
370
371 pub fn value_type(&self) -> ValueType {
372 self.as_ref().value_type()
373 }
374
375 pub fn flags(&self) -> &[LegacyFlag<'buf>] {
379 match self {
380 Self::Modern(_) => &[],
381 Self::Legacy(l) => l.flags(),
382 }
383 }
384
385 pub fn count(&self) -> usize {
389 self.as_ref().count()
390 }
391
392 pub fn data_size(&self) -> usize {
397 self.as_ref().data_size()
398 }
399}
400
401impl<'t, 'buf> CompatColumnRef<'t, 'buf> {
402 pub fn label(&self) -> Label<'t> {
405 match self {
406 Self::Modern(m) => m.label().as_ref(),
407 Self::Legacy(l) => l.label().into(),
408 }
409 }
410
411 pub fn value_type(&self) -> ValueType {
412 match self {
413 Self::Modern(m) => m.value_type(),
414 Self::Legacy(l) => l.value_type(),
415 }
416 }
417
418 pub fn flags(&self) -> &[LegacyFlag<'buf>] {
422 match self {
423 Self::Modern(_) => &[],
424 Self::Legacy(l) => l.flags(),
425 }
426 }
427
428 pub fn count(&self) -> usize {
432 match self {
433 Self::Modern(_) => 1,
434 Self::Legacy(l) => l.count(),
435 }
436 }
437
438 pub fn data_size(&self) -> usize {
443 match self {
444 Self::Modern(m) => m.data_size(),
445 Self::Legacy(l) => l.data_size(),
446 }
447 }
448}
449
450impl<'b> CompatRow<'b> {
451 pub fn cells(&self) -> impl Iterator<Item = Cell<'b>> + '_ {
456 match self {
457 CompatRow::Modern(m) => {
458 CompatIter::Modern(m.values.iter().map(|v| Cell::Single(v.clone())))
459 }
460 CompatRow::Legacy(l) => CompatIter::Legacy(l.cells.iter().cloned()),
461 }
462 }
463
464 pub fn into_cells(self) -> impl Iterator<Item = Cell<'b>> {
469 match self {
470 CompatRow::Modern(m) => CompatIter::Modern(m.into_values().map(Cell::Single)),
471 CompatRow::Legacy(l) => CompatIter::Legacy(l.into_cells()),
472 }
473 }
474}
475
476impl<'t, 'b> CompatRef<'t, 'b> {
477 pub fn cells(&self) -> impl Iterator<Item = Cell<'b>> + '_ {
478 match self {
479 CompatRef::Modern(m) => {
480 CompatIter::Modern(m.values.iter().map(|v| Cell::Single(v.clone())))
481 }
482 CompatRef::Legacy(l) => CompatIter::Legacy(l.cells.iter().cloned()),
483 }
484 }
485}
486
487impl<'buf> From<LegacyColumn<'buf>> for CompatColumn<'buf> {
488 fn from(value: LegacyColumn<'buf>) -> Self {
489 Self::Legacy(value)
490 }
491}
492
493impl<'buf> From<ModernColumn<'buf>> for CompatColumn<'buf> {
494 fn from(value: ModernColumn<'buf>) -> Self {
495 Self::Modern(value)
496 }
497}
498
499impl<'t, 'buf> From<&'t LegacyColumn<'buf>> for CompatColumnRef<'t, 'buf> {
500 fn from(value: &'t LegacyColumn<'buf>) -> Self {
501 Self::Legacy(value)
502 }
503}
504
505impl<'t, 'buf> From<&'t ModernColumn<'buf>> for CompatColumnRef<'t, 'buf> {
506 fn from(value: &'t ModernColumn<'buf>) -> Self {
507 Self::Modern(value)
508 }
509}
510
511impl<'buf> Table<'buf> for CompatTable<'buf> {
512 type Id = RowId;
513 type Name = Label<'buf>;
514 type Row = CompatRow<'buf>;
515 type BuilderRow = Infallible; type Column = CompatColumn<'buf>;
517 type BuilderColumn = CompatColumn<'buf>;
518}
519
520impl<'t, 'b> CellAccessor for CompatRef<'t, 'b> {
521 type Target = Cell<'b>;
522
523 fn access(self, pos: usize) -> Option<Self::Target> {
524 match self {
525 CompatRef::Modern(m) => m.values.get(pos).map(|v| Cell::Single(v.clone())),
526 CompatRef::Legacy(l) => l.cells.get(pos).cloned(),
527 }
528 }
529}
530
531impl<'t, 'b> LabelMap for CompatColumnMap<'t, 'b> {
532 type Name = Label<'b>;
533
534 fn position(&self, label: &Self::Name) -> Option<usize> {
535 match self {
536 CompatColumnMap::Modern(m) => m.position(label),
537 CompatColumnMap::Legacy(l) => {
538 let Label::String(s) = label else { return None };
539 l.position(s)
540 }
541 }
542 }
543}
544
545impl<'buf> ColumnSerialize for CompatColumn<'buf> {
546 fn ser_value_type(&self) -> crate::ValueType {
547 self.value_type()
548 }
549
550 fn ser_flags(&self) -> &[LegacyFlag] {
551 match self {
552 Self::Modern(m) => m.ser_flags(),
553 Self::Legacy(l) => l.ser_flags(),
554 }
555 }
556}
557
558impl<'a, 'buf> ColumnSerialize for CompatColumnRef<'a, 'buf> {
559 fn ser_value_type(&self) -> crate::ValueType {
560 self.value_type()
561 }
562
563 fn ser_flags(&self) -> &[LegacyFlag] {
564 match self {
565 Self::Modern(m) => m.ser_flags(),
566 Self::Legacy(l) => l.ser_flags(),
567 }
568 }
569}
570
571impl<'buf> Column for CompatColumn<'buf> {
572 type Name = Label<'buf>;
573
574 fn value_type(&self) -> ValueType {
575 self.value_type()
576 }
577
578 fn clone_label(&self) -> Self::Name {
579 match self {
580 Self::Modern(m) => m.label.clone(),
581 Self::Legacy(l) => Label::String(l.label.clone()),
582 }
583 }
584}
585
586impl<'a, 'buf> Column for CompatColumnRef<'a, 'buf> {
587 type Name = Label<'buf>;
588
589 fn value_type(&self) -> ValueType {
590 self.value_type()
591 }
592
593 fn clone_label(&self) -> Self::Name {
594 match self {
595 Self::Modern(m) => m.label.clone(),
596 Self::Legacy(l) => Label::String(l.label.clone()),
597 }
598 }
599}