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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//! The [`MlDataset`] trait shared by every loader in this crate.
//!
//! Every loader parses into a [`Table`], so the trait needs no type parameter and
//! no per-loader accessor. It covers the container operations that stay the same
//! whatever the table holds:
//!
//! - [`invalidate`](MlDataset::invalidate) drops the in-memory cache and forces the
//! next access to re-read (and re-verify) the file on disk.
//! - [`is_loaded`](MlDataset::is_loaded) and [`storage_dir`](MlDataset::storage_dir)
//! let you inspect a loader without touching the data.
//! - [`n_samples`](MlDataset::n_samples) gives the sample count.
//!
//! This trait names its data accessors [`load`](MlDataset::load),
//! [`peek`](MlDataset::peek), and [`unload`](MlDataset::unload) rather than reusing
//! `data`, `get_data`, and `take_data`. This way, a trait method never silently
//! shadows the inherent method of the same name, and the inherent method never
//! shadows the trait method either. Both sets are always available and always
//! agree. Use whichever reads better where you are.
//!
//! This module is always available. The `dataset` feature only decides whether the
//! built-in loaders that implement the trait compile with it.
//!
//! # Example
//!
//! This example needs the `dataset` feature, because it uses two built-in loaders.
//!
//! ```no_run
//! use dataset_ml::traits::MlDataset;
//! use dataset_ml::{Iris, SmsSpam};
//!
//! // One function works for any loader, including the text corpora, whose table
//! // holds entirely different columns from Iris's.
//! fn describe<D: MlDataset>(dataset: &D) -> String {
//! format!("{} ({} samples)", D::NAME, dataset.n_samples().unwrap())
//! }
//!
//! assert_eq!(describe(&Iris::new("./data")), "iris (150 samples)");
//! assert_eq!(describe(&SmsSpam::new("./data")), "sms_spam (5574 samples)");
//! ```
use crateTable;
use ;
/// The lazy-loading behavior every dataset loader in this crate shares.
///
/// Implementors wrap a [`Dataset<Table, DatasetError>`](dataset_core::Dataset) and
/// only need to expose it through the three needed methods. The trait provides
/// everything else.
///
/// # Implementing it for your own loader
///
/// ```rust
/// use dataset_core::{Dataset, DatasetError};
/// use dataset_ml::table::Table;
/// use dataset_ml::traits::MlDataset;
///
/// struct MyDataset {
/// dataset: Dataset<Table, DatasetError>,
/// }
///
/// impl MlDataset for MyDataset {
/// const NAME: &'static str = "my_dataset";
///
/// fn dataset(&self) -> &Dataset<Table, DatasetError> {
/// &self.dataset
/// }
///
/// fn dataset_mut(&mut self) -> &mut Dataset<Table, DatasetError> {
/// &mut self.dataset
/// }
///
/// fn into_dataset(self) -> Dataset<Table, DatasetError> {
/// self.dataset
/// }
/// }
/// ```
/// Implement [`MlDataset`] for a loader that stores its container in a field named
/// `dataset`.
///
/// Every loader in this crate has that exact shape, so the implementation is
/// entirely mechanical. This macro writes the three needed methods and leaves the
/// rest to the trait's defaults. It is crate-internal. Downstream loaders
/// implement the trait directly (see [`MlDataset`]'s own example).
pub use impl_ml_dataset;