ic/
read.rs

1//! Dedicated to reading data.
2
3use anyhow::Context;
4
5use crate::{
6    app_cfg, read, ClassifiedIris, UnclassifiedIris, PATH_TO_TESTING_IRISES,
7    PATH_TO_TRAINING_IRISES,
8};
9
10// Helpful local type aliases.
11type UnclassifiedIrises = Vec<UnclassifiedIris>;
12type ClassifiedIrises = Vec<ClassifiedIris>;
13
14/// Reads users data from stdin.
15///
16/// Returned error reports what failed, not only why.
17pub fn user_irises() -> anyhow::Result<UnclassifiedIrises> {
18    let mut irises_reader = csv::ReaderBuilder::new()
19        .has_headers(false)
20        .delimiter(app_cfg().separator.into())
21        .from_reader(std::io::stdin().lock());
22    let irises: Result<Vec<_>, _> = irises_reader.deserialize().collect();
23    Ok(irises.context("Failed to read unclassified irises from stdin.")?)
24}
25
26/// Reads the training data from pre-existing file in [`PATH_TO_TRAINING_IRISES`].
27///
28/// Returned error reports what failed, not only why.
29pub fn training_irises() -> anyhow::Result<ClassifiedIrises> {
30    (|| -> Result<_, _> {
31        let mut irises_reader = csv::ReaderBuilder::new()
32            .has_headers(false)
33            .from_path(PATH_TO_TRAINING_IRISES)?;
34        let result: Result<Vec<_>, _> = irises_reader.deserialize().collect();
35        result
36    })()
37    .with_context(|| {
38        format!("Failed to read classified irises from \"{PATH_TO_TRAINING_IRISES}\".")
39    })
40}
41
42/// Returned error reports what failed, not only why.
43pub fn testing_irises() -> anyhow::Result<ClassifiedIrises> {
44    (|| -> Result<_, _> {
45        let mut irises_reader = csv::ReaderBuilder::new()
46            .has_headers(false)
47            .from_path(PATH_TO_TESTING_IRISES)?;
48        let result: Result<Vec<_>, _> = irises_reader.deserialize().collect();
49        result
50    })()
51    .with_context(|| format!("Failed to read testing irises from \"{PATH_TO_TESTING_IRISES}\"."))
52}
53
54#[deprecated]
55pub fn data() -> anyhow::Result<(UnclassifiedIrises, ClassifiedIrises)> {
56    // Reading both data sets in parallel.
57    let (unclassified_irises, classified_irises) =
58        rayon::join(|| read::user_irises(), || read::training_irises());
59    // Passing errors up with some context.
60    (|| -> anyhow::Result<_> { Ok((unclassified_irises?, classified_irises?)) })()
61        .context("Reading of the data failed.")
62}