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
#[cfg(feature = "std")]
use std::ops::Index;
use std::collections::HashMap;

#[cfg(feature = "std")]
/// Represents a single row of data
#[derive(Debug, Clone)]
pub struct Entry {
    index: usize,
    value_iter: Vec<(String, String)>,
    null_val: String,
    pub values: HashMap<String, String>,
}

/// Represents the entire parsed content
#[derive(Debug, Clone)]
pub struct Content {
    index: usize,
    pub columns: Vec<String>,
    pub raw_lines: Vec<String>,
    pub rows: Vec<Entry>,
}

#[cfg(feature = "std")]
impl Index<usize> for Content {
    type Output = Entry;

    fn index(&self, field: usize) -> &Entry {
        &self.rows[field]
    }
}

impl Index<&str> for Entry {
    type Output = String;

    fn index(&self, field: &str) -> &Self::Output {
        let v = self.values.get(field);

        return if v.is_some() {
            v.unwrap()
        } else {
            &self.null_val
        }
    }
}

#[cfg(feature = "std")]
impl Iterator for Content {
    type Item = Entry;

    fn next(&mut self) -> Option<Self::Item> {
        let i = self.index;
        self.index += 1;
        return if self.rows.len() - 1 > i {
            Some(self.rows[i].clone())
        } else {
            None
        };
    }
}

impl Iterator for Entry {
    type Item = (String, String);

    fn next(&mut self) -> Option<Self::Item> {
        let i = self.index;
        self.index += 1;
        return if self.value_iter.len() - 1 > i {
            Some(self.value_iter[i].clone())
        } else {
            None
        };
    }
}

impl Content {
    pub(crate) fn new() -> Content {
        Content {
            index: 0,
            columns: Vec::new(),
            raw_lines: Vec::new(),
            rows: Vec::new(),
        }
    }
}

impl Entry {
    pub(crate) fn from_vec(columns: Vec<String>, headers: Option<Vec<String>>) -> Entry {
        let mut v = Entry {
            index: 0,
            value_iter: Vec::new(),
            null_val: String::new(),
            values: HashMap::new(),
        };
        let h = headers.unwrap_or(Vec::new());
        let mut index = 0;
        for column in columns {
            if h.len() > 0 {
                v.values.insert(h[index].clone(), column.clone());
                v.value_iter.push((h[index].clone(), column));
            } else {
                v.values.insert(index.to_string(), column.clone());
                v.value_iter.push((index.to_string(), column));
            }
            index += 1;
        };
        v
    }
}