1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
/*! Type aliases and macro for handling specifications of fields in a data source. */ use std::marker::PhantomData; use label::*; /// Type alias for a field label and data type. pub type FieldSpec<Label, DType> = Labeled<Label, PhantomData<DType>>; /// Type alias for an `LVCons`-list which only contains the data type information for the identified /// field. pub type FieldCons<Label, DType, Tail> = LMCons<Label, DType, Tail>; /// Type alias for a cons-list containing a labeled field, it's data type, and an arbitrary payload. pub type FieldPayloadCons<Label, DType, Payload, Tail> = LDVCons<Label, DType, Payload, Tail>; /// Designation of a field in a data source -- either a field name or a field index. #[derive(Debug, Clone)] pub enum FieldDesignator { /// Field / column name in data source. Expr(String), /// Field / column index in data source. Idx(usize), } impl SelfValued for FieldDesignator {} /// Type alias for a cons-list containing fields with their labels, data type, and source /// designators. pub type SpecCons<Label, DType, Tail> = FieldPayloadCons<Label, DType, FieldDesignator, Tail>; impl<Label, DType, Tail> SpecCons<Label, DType, Tail> { /// Create a new `SpecCons` cons-list from a [FieldDesignator](enum.FieldDesignator.html). pub fn new(src_designator: FieldDesignator, tail: Tail) -> SpecCons<Label, DType, Tail> { SpecCons { head: TypedValue::from(src_designator).into(), tail, } } } /// Macro for creating a source specification structure used to specify how to /// extract fields from a data source. It correlates labels (defined using the /// [tablespace](macro.tablespace.html) macro) to field / column names or indices in a /// data source. This source specification structure is implemented as a // [SpecCons](fieldlist/type.SpecCons.html) cons-list. /// /// The `spec` macro syntax is a list of `fieldname` or `fieldindex` declarations that connect /// field labels to either column titles or column indices (starting from 0), respectively. /// /// # Examples /// /// This example defines a source specification with three column names: the `CountryName` field /// label will take data from the column with the "Country Name" header, the `CountryCode` field /// label will take data from the 0th (first) column, and the `Gdp2015` field label will take /// data from the column with the "2015" label. /// /// This example also shows the usage of the [tablespace](macro.tablespace.html) macro; see that /// macro's documentation for its syntax and an example. /// /// ``` /// # #[macro_use] extern crate agnes; /// /// tablespace![ /// table gdp { /// CountryName: String, /// CountryCode: String, /// Gdp2015: f64, /// } /// ]; /// /// fn main() { /// let gdp_spec = spec![ /// fieldname gdp::CountryName = "Country Name"; /// fieldname gdp::CountryCode = 0usize; /// fieldname gdp::Gdp2015 = "2015"; /// ]; /// // ... /// } /// ``` #[macro_export] macro_rules! spec { () => {{ $crate::cons::Nil }}; (fieldname $field_label:ty = $header:expr; $($rest:tt)*) => {{ use $crate::fieldlist::{FieldDesignator, SpecCons}; SpecCons::< $field_label, <$field_label as $crate::label::Typed>::DType, _, >::new( FieldDesignator::Expr($header.to_string()), spec![$($rest)*] ) }}; (fieldindex $field_label:ty = $idx:expr; $($rest:tt)*) => {{ use $crate::fieldlist::{FieldDesignator, SpecCons}; SpecCons::< $field_label, <$field_label as $crate::label::Typed>::DType, _, >::new( FieldDesignator::Idx($idx), spec![$($rest)*] ) }}; }