1use std::fmt::Debug;
7use std::ops::Deref;
8use std::rc::Rc;
9
10#[cfg(feature = "serialize")]
11use serde::ser::{Serialize, Serializer};
12use typenum::uint::UTerm;
13
14use access::{DataIndex, NRows};
15use cons::*;
16use error;
17use field::{FieldData, Value};
18use fieldlist::{FieldCons, FieldPayloadCons, FieldSchema};
19use frame::{DataFrame, SimpleFrameFields};
20use label::*;
21use select::{FieldSelect, SelectFieldByLabel};
22use view::{DataView, FrameLookupCons, ViewFrameCons};
23
24#[derive(Debug, Hash, PartialEq, Eq)]
26pub struct DataRef<DType>(pub Rc<FieldData<DType>>);
27
28impl<DType> DataRef<DType> {
29 fn new(field: FieldData<DType>) -> DataRef<DType> {
30 DataRef(Rc::new(field))
31 }
32}
33
34impl<DType> Clone for DataRef<DType> {
35 fn clone(&self) -> DataRef<DType> {
36 DataRef(Rc::clone(&self.0))
37 }
38}
39
40impl<T> Deref for DataRef<T> {
41 type Target = FieldData<T>;
42
43 fn deref(&self) -> &FieldData<T> {
44 &self.0.deref()
45 }
46}
47
48impl<T> From<FieldData<T>> for DataRef<T> {
49 fn from(orig: FieldData<T>) -> DataRef<T> {
50 DataRef(Rc::new(orig))
51 }
52}
53
54impl<T> DataIndex for DataRef<T>
55where
56 FieldData<T>: DataIndex<DType = T>,
57 T: Debug,
58{
59 type DType = T;
60
61 fn get_datum(&self, idx: usize) -> error::Result<Value<&T>> {
62 <FieldData<T> as DataIndex>::get_datum(&self.0, idx)
63 }
64 fn len(&self) -> usize {
65 <FieldData<T> as DataIndex>::len(&self.0)
66 }
67}
68
69#[cfg(feature = "serialize")]
70impl<T> Serialize for DataRef<T>
71where
72 T: Serialize,
73{
74 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75 where
76 S: Serializer,
77 {
78 self.0.serialize(serializer)
79 }
80}
81
82pub type StorageCons<Label, DType, Tail> = FieldPayloadCons<Label, DType, DataRef<DType>, Tail>;
85
86#[derive(Debug)]
90pub struct DataStore<Fields: AssocStorage> {
91 data: Fields::Storage,
92}
93
94pub trait AssocStorage {
96 type Storage: Debug;
98}
99impl<Label, DType, Tail> AssocStorage for FieldCons<Label, DType, Tail>
100where
101 Tail: AssocStorage,
102 Label: Debug,
103 DType: Debug,
104{
105 type Storage = StorageCons<Label, DType, Tail::Storage>;
106}
107impl AssocStorage for Nil {
108 type Storage = Nil;
109}
110
111impl<Fields> DataStore<Fields>
112where
113 Fields: AssocStorage,
114{
115 pub fn empty() -> DataStore<Nil> {
117 DataStore { data: Nil }
118 }
119}
120
121impl<Fields> NRows for DataStore<Fields>
122where
123 Fields: AssocStorage,
124 Fields::Storage: NRows,
125{
126 fn nrows(&self) -> usize {
127 self.data.nrows()
128 }
129}
130
131pub type NewFieldStorage<NewLabel, NewDType> =
134 Labeled<NewLabel, TypedValue<NewDType, DataRef<NewDType>>>;
135
136macro_rules! make_add_field {
137 (
138 $(#[$add_trait_doc:meta])* trait $add_trait:tt;
139 $(#[$add_fn_doc:meta])* fn $add_fn:tt;
140
141 $(#[$add_valiter_trait_doc:meta])* trait $add_valiter_trait:tt;
142 $(#[$add_valiter_fn_doc:meta])* fn $add_valiter_fn:tt;
143
144 $(#[$add_iter_trait_doc:meta])* trait $add_iter_trait:tt;
145 $(#[$add_iter_fn_doc:meta])* fn $add_iter_fn:tt;
146
147 $(#[$add_cloned_valiter_trait_doc:meta])* trait $add_cloned_valiter_trait:tt;
148 $(#[$add_cloned_valiter_fn_doc:meta])* fn $add_cloned_valiter_fn:tt;
149
150 $(#[$add_cloned_iter_trait_doc:meta])* trait $add_cloned_iter_trait:tt;
151 $(#[$add_cloned_iter_fn_doc:meta])* fn $add_cloned_iter_fn:tt;
152
153 $(#[$add_empty_trait_doc:meta])* trait $add_empty_trait:tt;
154 $(#[$add_empty_fn_doc:meta])* fn $add_empty_fn:tt;
155
156 $push_trait:tt $push_fn:tt $pushed_alias:tt
157 ) => {
158 pub type $pushed_alias<PrevFields, NewLabel, NewDType> =
160 <PrevFields as $push_trait<FieldSchema<NewLabel, NewDType>>>::Output;
161
162 $(#[$add_trait_doc])*
163 pub trait $add_trait<NewLabel, NewDType> {
164 type OutputFields: AssocStorage;
166
167 $(#[$add_fn_doc])*
168 fn $add_fn(self, data: FieldData<NewDType>) -> DataStore<Self::OutputFields>;
169 }
170
171 impl<PrevFields, NewLabel, NewDType> $add_trait<NewLabel, NewDType>
172 for DataStore<PrevFields>
173 where
174 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
175 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
176 PrevFields::Storage: $push_trait<
177 NewFieldStorage<NewLabel, NewDType>,
178 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
179 >,
180 NewLabel: Debug,
181 NewDType: Debug,
182 {
183 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
184
185 fn $add_fn(self, data: FieldData<NewDType>) -> DataStore<Self::OutputFields> {
186 DataStore {
187 data: self
188 .data
189 .$push_fn(TypedValue::from(DataRef::new(data)).into()),
190 }
191 }
192 }
193
194 $(#[$add_valiter_trait_doc])*
195 pub trait $add_valiter_trait<NewLabel, NewDType> {
196 type OutputFields: AssocStorage;
198
199 $(#[$add_valiter_fn_doc])*
200 fn $add_valiter_fn<IntoIter, Iter>(
201 self,
202 iter: IntoIter,
203 ) -> DataStore<Self::OutputFields>
204 where
205 Iter: Iterator<Item = Value<NewDType>>,
206 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<NewDType>>;
207 }
208 impl<PrevFields, NewLabel, NewDType> $add_valiter_trait<NewLabel, NewDType>
209 for DataStore<PrevFields>
210 where
211 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
212 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
213 PrevFields::Storage: $push_trait<
214 NewFieldStorage<NewLabel, NewDType>,
215 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
216 >,
217 NewLabel: Debug,
218 NewDType: Default + Debug,
219 {
220 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
221
222 fn $add_valiter_fn<IntoIter, Iter>(
223 self,
224 iter: IntoIter,
225 ) -> DataStore<Self::OutputFields>
226 where
227 Iter: Iterator<Item = Value<NewDType>>,
228 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<NewDType>>,
229 {
230 DataStore {
231 data: self.data.$push_fn(
232 TypedValue::from(DataRef::new(
233 iter.into_iter().collect::<FieldData<NewDType>>(),
234 ))
235 .into(),
236 ),
237 }
238 }
239 }
240
241 $(#[$add_iter_trait_doc])*
242 pub trait $add_iter_trait<NewLabel, NewDType> {
243 type OutputFields: AssocStorage;
245
246 $(#[$add_iter_fn_doc])*
247 fn $add_iter_fn<IntoIter, Iter>(self, iter: IntoIter) -> DataStore<Self::OutputFields>
248 where
249 Iter: Iterator<Item = NewDType>,
250 IntoIter: IntoIterator<IntoIter = Iter, Item = NewDType>;
251 }
252 impl<PrevFields, NewLabel, NewDType> $add_iter_trait<NewLabel, NewDType>
253 for DataStore<PrevFields>
254 where
255 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
256 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
257 PrevFields::Storage: $push_trait<
258 NewFieldStorage<NewLabel, NewDType>,
259 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
260 >,
261 NewLabel: Debug,
262 NewDType: Debug,
263 {
264 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
265
266 fn $add_iter_fn<IntoIter, Iter>(self, iter: IntoIter) -> DataStore<Self::OutputFields>
267 where
268 Iter: Iterator<Item = NewDType>,
269 IntoIter: IntoIterator<IntoIter = Iter, Item = NewDType>,
270 {
271 DataStore {
272 data: self.data.$push_fn(
273 TypedValue::from(DataRef::new(
274 iter.into_iter().collect::<FieldData<NewDType>>(),
275 ))
276 .into(),
277 ),
278 }
279 }
280 }
281
282 $(#[$add_cloned_valiter_trait_doc])*
283 pub trait $add_cloned_valiter_trait<NewLabel, NewDType> {
284 type OutputFields: AssocStorage;
286
287 $(#[$add_cloned_valiter_fn_doc])*
288 fn $add_cloned_valiter_fn<'a, IntoIter, Iter>(
289 self,
290 iter: IntoIter,
291 ) -> DataStore<Self::OutputFields>
292 where
293 Iter: Iterator<Item = Value<&'a NewDType>>,
294 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<&'a NewDType>>,
295 NewDType: 'a;
296 }
297 impl<PrevFields, NewLabel, NewDType> $add_cloned_valiter_trait<NewLabel, NewDType>
298 for DataStore<PrevFields>
299 where
300 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
301 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
302 PrevFields::Storage: $push_trait<
303 NewFieldStorage<NewLabel, NewDType>,
304 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
305 >,
306 NewLabel: Debug,
307 NewDType: Default + Clone + Debug,
308 {
309 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
310
311 fn $add_cloned_valiter_fn<'a, IntoIter, Iter>(
312 self,
313 iter: IntoIter,
314 ) -> DataStore<Self::OutputFields>
315 where
316 Iter: Iterator<Item = Value<&'a NewDType>>,
317 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<&'a NewDType>>,
318 NewDType: 'a,
319 {
320 DataStore {
321 data: self.data.$push_fn(
322 TypedValue::from(DataRef::new(
323 iter.into_iter()
324 .map(|x| x.clone())
325 .collect::<FieldData<NewDType>>(),
326 ))
327 .into(),
328 ),
329 }
330 }
331 }
332
333 $(#[$add_cloned_iter_trait_doc])*
334 pub trait $add_cloned_iter_trait<NewLabel, NewDType> {
335 type OutputFields: AssocStorage;
337
338 $(#[$add_cloned_iter_fn_doc])*
339 fn $add_cloned_iter_fn<'a, IntoIter, Iter>(
340 self,
341 iter: IntoIter,
342 ) -> DataStore<Self::OutputFields>
343 where
344 Iter: Iterator<Item = &'a NewDType>,
345 IntoIter: IntoIterator<IntoIter = Iter, Item = &'a NewDType>,
346 NewDType: 'a;
347 }
348 impl<PrevFields, NewLabel, NewDType> $add_cloned_iter_trait<NewLabel, NewDType>
349 for DataStore<PrevFields>
350 where
351 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
352 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
353 PrevFields::Storage: $push_trait<
354 NewFieldStorage<NewLabel, NewDType>,
355 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
356 >,
357 NewLabel: Debug,
358 NewDType: Clone + Debug,
359 {
360 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
361
362 fn $add_cloned_iter_fn<'a, IntoIter, Iter>(
363 self,
364 iter: IntoIter,
365 ) -> DataStore<Self::OutputFields>
366 where
367 Iter: Iterator<Item = &'a NewDType>,
368 IntoIter: IntoIterator<IntoIter = Iter, Item = &'a NewDType>,
369 NewDType: 'a,
370 {
371 DataStore {
372 data: self.data.$push_fn(
373 TypedValue::from(DataRef::new(
374 iter.into_iter()
375 .map(|x| x.clone())
376 .collect::<FieldData<NewDType>>(),
377 ))
378 .into(),
379 ),
380 }
381 }
382 }
383
384 $(#[$add_empty_trait_doc])*
385 pub trait $add_empty_trait<NewLabel, NewDType> {
386 type OutputFields: AssocStorage;
388
389 $(#[$add_empty_fn_doc])*
390 fn $add_empty_fn(self) -> DataStore<Self::OutputFields>;
391 }
392 impl<PrevFields, NewLabel, NewDType> $add_empty_trait<NewLabel, NewDType>
393 for DataStore<PrevFields>
394 where
395 PrevFields: AssocStorage + $push_trait<FieldSchema<NewLabel, NewDType>>,
396 $pushed_alias<PrevFields, NewLabel, NewDType>: AssocStorage,
397 PrevFields::Storage: $push_trait<
398 NewFieldStorage<NewLabel, NewDType>,
399 Output = <$pushed_alias<PrevFields, NewLabel, NewDType> as AssocStorage>::Storage,
400 >,
401 NewLabel: Debug,
402 NewDType: Debug,
403 {
404 type OutputFields = $pushed_alias<PrevFields, NewLabel, NewDType>;
405
406 fn $add_empty_fn(self) -> DataStore<Self::OutputFields> {
407 DataStore {
408 data: self
409 .data
410 .$push_fn(TypedValue::from(DataRef::new(FieldData::default())).into()),
411 }
412 }
413 }
414
415 impl<PrevFields> DataStore<PrevFields>
416 where
417 PrevFields: AssocStorage,
418 {
419 $(#[$add_fn_doc])*
420 pub fn $add_fn<NewLabel, NewDType>(
421 self,
422 data: FieldData<NewDType>,
423 ) -> DataStore<<Self as $add_trait<NewLabel, NewDType>>::OutputFields>
424 where
425 Self: $add_trait<NewLabel, NewDType>,
426 {
427 $add_trait::$add_fn(self, data)
428 }
429
430 $(#[$add_valiter_fn_doc])*
431 pub fn $add_valiter_fn<NewLabel, NewDType, IntoIter, Iter>(
432 self,
433 iter: IntoIter,
434 ) -> DataStore<<Self as $add_valiter_trait<NewLabel, NewDType>>::OutputFields>
435 where
436 Iter: Iterator<Item = Value<NewDType>>,
437 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<NewDType>>,
438 Self: $add_valiter_trait<NewLabel, NewDType>,
439 {
440 $add_valiter_trait::$add_valiter_fn(self, iter)
441 }
442
443 $(#[$add_iter_fn_doc])*
444 pub fn $add_iter_fn<NewLabel, NewDType, IntoIter, Iter>(
445 self,
446 iter: IntoIter,
447 ) -> DataStore<<Self as $add_iter_trait<NewLabel, NewDType>>::OutputFields>
448 where
449 Iter: Iterator<Item = NewDType>,
450 IntoIter: IntoIterator<IntoIter = Iter, Item = NewDType>,
451 Self: $add_iter_trait<NewLabel, NewDType>,
452 {
453 $add_iter_trait::$add_iter_fn(self, iter)
454 }
455
456 $(#[$add_cloned_valiter_fn_doc])*
457 pub fn $add_cloned_valiter_fn<'a, NewLabel, NewDType, IntoIter, Iter>(
458 self,
459 iter: IntoIter,
460 ) -> DataStore<<Self as $add_cloned_valiter_trait<NewLabel, NewDType>>::OutputFields>
461 where
462 Iter: Iterator<Item = Value<&'a NewDType>>,
463 IntoIter: IntoIterator<IntoIter = Iter, Item = Value<&'a NewDType>>,
464 Self: $add_cloned_valiter_trait<NewLabel, NewDType>,
465 NewDType: 'a,
466 {
467 $add_cloned_valiter_trait::$add_cloned_valiter_fn(self, iter)
468 }
469 $(#[$add_cloned_iter_fn_doc])*
470 pub fn $add_cloned_iter_fn<'a, NewLabel, NewDType, IntoIter, Iter>(
471 self,
472 iter: IntoIter,
473 ) -> DataStore<<Self as $add_cloned_iter_trait<NewLabel, NewDType>>::OutputFields>
474 where
475 Iter: Iterator<Item = &'a NewDType>,
476 IntoIter: IntoIterator<IntoIter = Iter, Item = &'a NewDType>,
477 Self: $add_cloned_iter_trait<NewLabel, NewDType>,
478 NewDType: 'a,
479 {
480 $add_cloned_iter_trait::$add_cloned_iter_fn(self, iter)
481 }
482
483 $(#[$add_empty_fn_doc])*
484 pub fn $add_empty_fn<NewLabel, NewDType>(
485 self,
486 ) -> DataStore<<Self as $add_empty_trait<NewLabel, NewDType>>::OutputFields>
487 where
488 Self: $add_empty_trait<NewLabel, NewDType>,
489 {
490 $add_empty_trait::$add_empty_fn(self)
491 }
492 }
493 };
494}
495
496make_add_field![
497 trait PushFrontField;
500 fn push_front_field;
503
504 trait PushFrontFromValueIter;
507 fn push_front_from_value_iter;
510
511 trait PushFrontFromIter;
514 fn push_front_from_iter;
517
518 trait PushFrontClonedFromValueIter;
521 fn push_front_cloned_from_value_iter;
524
525 trait PushFrontClonedFromIter;
529 fn push_front_cloned_from_iter;
532
533 trait PushFrontEmpty;
536 fn push_front_empty;
538
539 PushFront push_front PushedFrontField
540];
541
542make_add_field![
543 trait PushBackField;
546 fn push_back_field;
549
550 trait PushBackFromValueIter;
553 fn push_back_from_value_iter;
556
557 trait PushBackFromIter;
560 fn push_back_from_iter;
563
564 trait PushBackClonedFromValueIter;
567 fn push_back_cloned_from_value_iter;
570
571 trait PushBackClonedFromIter;
575 fn push_back_cloned_from_iter;
578
579 trait PushBackEmpty;
582 fn push_back_empty;
584
585 PushBack push_back PushedBackField
586];
587
588impl<Label, Fields> SelectFieldByLabel<Label> for DataStore<Fields>
589where
590 Fields: AssocStorage,
591 Fields::Storage: LookupElemByLabel<Label>,
592 ElemOf<Fields::Storage, Label>: Typed,
593 ElemOf<Fields::Storage, Label>: Valued<Value = DataRef<TypeOfElemOf<Fields::Storage, Label>>>,
594 TypeOfElemOf<Fields::Storage, Label>: Debug,
595{
596 type DType = TypeOfElemOf<Fields::Storage, Label>;
597 type Output = DataRef<Self::DType>;
598
599 fn select_field(&self) -> Self::Output {
600 DataRef::clone(LookupElemByLabel::<Label>::elem(&self.data).value_ref())
601 }
602}
603impl<Fields> FieldSelect for DataStore<Fields> where Fields: AssocStorage {}
604
605pub trait AssocFrameLookup {
607 type Output;
609}
610impl AssocFrameLookup for Nil {
611 type Output = Nil;
612}
613impl<Label, Value, Tail> AssocFrameLookup for LVCons<Label, Value, Tail>
614where
615 Tail: AssocFrameLookup,
616{
617 type Output = FrameLookupCons<Label, UTerm, Label, <Tail as AssocFrameLookup>::Output>;
618}
619
620impl<Fields> DataStore<Fields>
621where
622 Fields: AssocStorage + AssocFrameLookup,
623{
624 pub fn into_view(self) -> <Self as IntoView>::Output
627 where
628 Self: IntoView,
629 {
630 IntoView::into_view(self)
631 }
632}
633
634pub trait IntoView {
637 type Labels;
639 type Frames;
641 type Output; fn into_view(self) -> Self::Output;
645}
646impl<Fields> IntoView for DataStore<Fields>
647where
648 Fields: AssocStorage + AssocFrameLookup + SimpleFrameFields,
649{
650 type Labels = <Fields as AssocFrameLookup>::Output;
651 type Frames = ViewFrameCons<UTerm, DataFrame<<Fields as SimpleFrameFields>::Fields, Self>, Nil>;
652 type Output = DataView<Self::Labels, Self::Frames>;
653
654 fn into_view(self) -> Self::Output {
655 DataView::new(ViewFrameCons {
656 head: DataFrame::from(self).into(),
657 tail: Nil,
658 })
659 }
660}
661
662pub type SingleFieldStore<Label, T> =
664 DataStore<<DataStore<Nil> as PushFrontFromValueIter<Label, T>>::OutputFields>;
665
666impl<Label, I, T> IntoView for Labeled<Label, I>
667where
668 I: Iterator<Item = Value<T>>,
669 DataStore<Nil>: PushFrontFromValueIter<Label, T>,
670 <DataStore<Nil> as PushFrontFromValueIter<Label, T>>::OutputFields:
671 AssocFrameLookup + SimpleFrameFields,
672{
673 type Labels = <SingleFieldStore<Label, T> as IntoView>::Labels;
674 type Frames = <SingleFieldStore<Label, T> as IntoView>::Frames;
675 type Output = <SingleFieldStore<Label, T> as IntoView>::Output;
676
677 fn into_view(self) -> Self::Output {
678 DataStore::<Nil>::empty()
679 .push_front_from_value_iter(self.value)
680 .into_view()
681 }
682}
683
684pub trait IntoStore<Label> {
687 type Output;
689
690 fn into_store(self) -> Self::Output;
692}
693
694impl<Label, T> IntoStore<Label> for FieldData<T>
695where
696 Label: Debug,
697 T: Default + Debug,
698{
699 type Output = SingleFieldStore<Label, T>;
700
701 fn into_store(self) -> Self::Output {
702 DataStore::<Nil>::empty().push_front_field(self)
703 }
704}
705
706#[cfg(test)]
707mod tests {
708
709 use std::fmt::Debug;
710 use std::path::Path;
711 use typenum::U0;
712
713 use csv_sniffer::metadata::Metadata;
714
715 use super::{DataStore, NRows};
716 use cons::*;
717 use field::Value;
718 use select::FieldSelect;
719 use source::csv::{CsvReader, CsvSource, IntoCsvSrcSchema};
720
721 fn load_csv_file<Schema>(
722 filename: &str,
723 spec: Schema,
724 ) -> (CsvReader<Schema::CsvSrcSchema>, Metadata)
725 where
726 Schema: IntoCsvSrcSchema,
727 <Schema as IntoCsvSrcSchema>::CsvSrcSchema: Debug,
728 {
729 let data_filepath = Path::new(file!()) .parent()
731 .unwrap() .parent()
733 .unwrap() .join("tests") .join("data") .join(filename); let source = CsvSource::new(data_filepath).unwrap();
739 (
740 CsvReader::new(&source, spec).unwrap(),
741 source.metadata().clone(),
742 )
743 }
744
745 tablespace![
746 pub table gdp {
747 CountryName: String,
748 CountryCode: String,
749 Year1983: f64,
750 }
751 ];
752
753 #[test]
754 fn storage_create() {
755 let ds = DataStore::<Nil>::empty();
756
757 type TestTablespace = U0;
758 first_label![Test, TestTablespace, u64];
759
760 let data = vec![
761 Value::Exists(4u64),
762 Value::Exists(1),
763 Value::Na,
764 Value::Exists(3),
765 Value::Exists(7),
766 Value::Exists(8),
767 Value::Na,
768 ];
769 let expected_nrows = data.len();
770
771 let ds = ds.push_back_from_iter::<Test, _, _, _>(data);
772 println!("{:?}", ds);
773 assert_eq!(ds.nrows(), expected_nrows);
774 assert_eq!(ds.field::<Test>().len(), expected_nrows);
775
776 let gdp_schema = schema![
777 fieldname gdp::CountryName = "Country Name";
778 fieldname gdp::CountryCode = "Country Code";
779 fieldname gdp::Year1983 = "1983";
780 ];
781
782 let (mut csv_rdr, _metadata) = load_csv_file("gdp.csv", gdp_schema.clone());
783 let ds = csv_rdr.read().unwrap();
784 const EXPECTED_GDP_NROWS: usize = 264;
785 assert_eq!(ds.nrows(), EXPECTED_GDP_NROWS);
786 assert_eq!(ds.field::<gdp::CountryName>().len(), EXPECTED_GDP_NROWS);
787 }
788}