flat/
schema.rs

1use std::marker::PhantomData;
2
3/// The internal trait which defines a schema.
4/// Consumers should not implement this trait.
5#[doc(hidden)]
6pub trait Schema {
7    type Dimensions;
8}
9
10/// Starting point for defining the dimensions of a dataset.
11///
12/// ```ignore
13/// use flat::Schema;
14///
15/// let my_schema = Schemas::two("dimension_0", "dimension_1");
16/// ```
17pub struct Schemas;
18
19impl Schemas {
20    /// Define a 1-dimensional schema.
21    /// The names of the dimensions are specified in order.
22    ///
23    /// ### Example
24    /// ```
25    /// use flat::*;
26    ///
27    /// // The inventory of animals in a zoo.
28    /// // This dataset has 2 bears, and 1 tiger.
29    /// let schema = Schemas::one("Animal");
30    /// let dataset = DatasetBuilder::new(schema)
31    ///     //   (Animal,)
32    ///     .add(("Bear",))
33    ///     .add(("Bear",))
34    ///     .add(("Tiger",))
35    ///     .build();
36    /// ```
37    pub fn one<T>(dimension_0: impl Into<String>) -> Schema1<T> {
38        Schema1 {
39            phantom_0: PhantomData,
40            dimension_0: dimension_0.into(),
41        }
42    }
43
44    /// Define a 2-dimensional schema.
45    /// The names of the dimensions are specified in order.
46    ///
47    /// ### Example
48    /// ```
49    /// use flat::*;
50    ///
51    /// // A dataset describing the zoo animal heights.
52    /// // This dataset has a bear which measures height "10", and another which measures height "11".
53    /// // There is also a tiger which measures height "5".
54    /// let schema = Schemas::two("Animal", "Height");
55    /// let dataset = DatasetBuilder::new(schema)
56    ///     //   (Animal, Height)
57    ///     .add(("Bear", 10))
58    ///     .add(("Bear", 11))
59    ///     .add(("Tiger", 5))
60    ///     .build();
61    /// ```
62    pub fn two<T, U>(
63        dimension_0: impl Into<String>,
64        dimension_1: impl Into<String>,
65    ) -> Schema2<T, U> {
66        Schema2 {
67            phantom_0: PhantomData,
68            dimension_0: dimension_0.into(),
69            phantom_1: PhantomData,
70            dimension_1: dimension_1.into(),
71        }
72    }
73
74    /// Define a 3-dimensional schema.
75    /// The names of the dimensions are specified in order.
76    ///
77    /// ### Example
78    /// ```
79    /// use flat::*;
80    ///
81    /// // A dataset with zoo animal heights and their enclosures.
82    /// // This dataset has a bear which measures height "10", and another which measures height "11".
83    /// // There is also a tiger which measures height "5".
84    /// // The bears live in Pen01, while the tiger lives in Pen02.
85    /// let schema = Schemas::three("Animal", "Height", "Enclosure");
86    /// let dataset = DatasetBuilder::new(schema)
87    ///     //   (Animal, Height, Enclosure)
88    ///     .add(("Bear", 10, "Pen01"))
89    ///     .add(("Bear", 11, "Pen01"))
90    ///     .add(("Tiger", 5, "Pen02"))
91    ///     .build();
92    /// ```
93    pub fn three<T, U, V>(
94        dimension_0: impl Into<String>,
95        dimension_1: impl Into<String>,
96        dimension_2: impl Into<String>,
97    ) -> Schema3<T, U, V> {
98        Schema3 {
99            phantom_0: PhantomData,
100            dimension_0: dimension_0.into(),
101            phantom_1: PhantomData,
102            dimension_1: dimension_1.into(),
103            phantom_2: PhantomData,
104            dimension_2: dimension_2.into(),
105        }
106    }
107
108    /// Define a 4-dimensional schema.
109    /// The names of the dimensions are specified in order.
110    ///
111    /// ### Example
112    /// ```
113    /// use flat::*;
114    ///
115    /// // A dataset with zoo animal heights and their enclosures.
116    /// // This dataset has a bear which measures height "10", and another which measures height "11".
117    /// // There is also a tiger which measures height "5".
118    /// // The bears live in Pen01 (North East quadrant), while the tiger lives in Pen02 (South West quadrant).
119    /// let schema = Schemas::four("Animal", "Height", "Enclosure", "Quadrant");
120    /// let dataset = DatasetBuilder::new(schema)
121    ///     //   (Animal, Height, Enclosure, Quadrant)
122    ///     .add(("Bear", 10, "Pen01", "NorthEast"))
123    ///     .add(("Bear", 11, "Pen01", "NorthEast"))
124    ///     .add(("Tiger", 5, "Pen02", "SouthWest"))
125    ///     .build();
126    /// ```
127    pub fn four<T, U, V, W>(
128        dimension_0: impl Into<String>,
129        dimension_1: impl Into<String>,
130        dimension_2: impl Into<String>,
131        dimension_3: impl Into<String>,
132    ) -> Schema4<T, U, V, W> {
133        Schema4 {
134            phantom_0: PhantomData,
135            dimension_0: dimension_0.into(),
136            phantom_1: PhantomData,
137            dimension_1: dimension_1.into(),
138            phantom_2: PhantomData,
139            dimension_2: dimension_2.into(),
140            phantom_3: PhantomData,
141            dimension_3: dimension_3.into(),
142        }
143    }
144}
145
146#[doc(hidden)]
147pub struct Schema1<T> {
148    pub(crate) phantom_0: PhantomData<T>,
149    pub(crate) dimension_0: String,
150}
151
152impl<T> Schema for Schema1<T> {
153    type Dimensions = (T,);
154}
155
156#[doc(hidden)]
157pub struct Schema2<T, U> {
158    pub(crate) phantom_0: PhantomData<T>,
159    pub(crate) dimension_0: String,
160    pub(crate) phantom_1: PhantomData<U>,
161    pub(crate) dimension_1: String,
162}
163
164impl<T, U> Schema for Schema2<T, U> {
165    type Dimensions = (T, U);
166}
167
168#[doc(hidden)]
169pub struct Schema3<T, U, V> {
170    pub(crate) phantom_0: PhantomData<T>,
171    pub(crate) dimension_0: String,
172    pub(crate) phantom_1: PhantomData<U>,
173    pub(crate) dimension_1: String,
174    pub(crate) phantom_2: PhantomData<V>,
175    pub(crate) dimension_2: String,
176}
177
178impl<T, U, V> Schema for Schema3<T, U, V> {
179    type Dimensions = (T, U, V);
180}
181
182#[doc(hidden)]
183#[allow(unused)]
184pub struct Schema4<T, U, V, W> {
185    pub(crate) phantom_0: PhantomData<T>,
186    pub(crate) dimension_0: String,
187    pub(crate) phantom_1: PhantomData<U>,
188    pub(crate) dimension_1: String,
189    pub(crate) phantom_2: PhantomData<V>,
190    pub(crate) dimension_2: String,
191    pub(crate) phantom_3: PhantomData<W>,
192    pub(crate) dimension_3: String,
193}
194
195impl<T, U, V, W> Schema for Schema4<T, U, V, W> {
196    type Dimensions = (T, U, V, W);
197}
198
199// TODO
200// pub struct Schema5<T, U, V, W, X>;
201// pub struct Schema6<T, U, V, W, X, Y>;
202// pub struct Schema7<T, U, V, W, X, Y, Z>;