rskit_dataset/record/
model.rs1use std::collections::BTreeMap;
4
5use serde_json::Value;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[non_exhaustive]
10pub enum DatasetFormat {
11 Csv,
13 JsonArray,
15 JsonLines,
17}
18
19#[derive(Debug, Clone, PartialEq)]
21pub struct DatasetRecord {
22 fields: BTreeMap<String, Value>,
23}
24
25impl DatasetRecord {
26 #[must_use]
28 pub fn new(fields: BTreeMap<String, Value>) -> Self {
29 Self { fields }
30 }
31
32 #[must_use]
34 pub fn from_fields<I, K>(fields: I) -> Self
35 where
36 I: IntoIterator<Item = (K, Value)>,
37 K: Into<String>,
38 {
39 Self {
40 fields: fields
41 .into_iter()
42 .map(|(key, value)| (key.into(), value))
43 .collect(),
44 }
45 }
46
47 #[must_use]
49 pub fn get(&self, name: &str) -> Option<&Value> {
50 self.fields.get(name)
51 }
52
53 #[must_use]
55 pub fn fields(&self) -> &BTreeMap<String, Value> {
56 &self.fields
57 }
58
59 #[must_use]
61 pub fn into_fields(self) -> BTreeMap<String, Value> {
62 self.fields
63 }
64
65 #[must_use]
67 pub fn select(&self, columns: &[String]) -> Self {
68 let fields = columns
69 .iter()
70 .filter_map(|column| {
71 self.fields
72 .get(column)
73 .map(|value| (column.clone(), value.clone()))
74 })
75 .collect();
76 Self { fields }
77 }
78
79 #[must_use]
81 pub fn into_json(self) -> Value {
82 Value::Object(self.fields.into_iter().collect())
83 }
84
85 #[must_use]
87 pub fn to_json(&self) -> Value {
88 Value::Object(self.fields.clone().into_iter().collect())
89 }
90}
91
92impl crate::DatasetItem for DatasetRecord {}
93
94#[cfg(test)]
95mod tests {
96 use serde_json::json;
97
98 use super::*;
99
100 #[test]
101 fn dataset_record_projection_and_json_are_deterministic() {
102 let record = DatasetRecord::new(
103 DatasetRecord::from_fields([("b", json!(2)), ("a", json!("one")), ("c", Value::Null)])
104 .into_fields(),
105 );
106
107 assert_eq!(record.get("a"), Some(&json!("one")));
108 assert_eq!(
109 record.fields().keys().cloned().collect::<Vec<_>>(),
110 ["a", "b", "c"]
111 );
112 let selected = record.select(&["c".to_string(), "missing".to_string(), "a".to_string()]);
113 assert_eq!(
114 selected.fields().keys().cloned().collect::<Vec<_>>(),
115 ["a", "c"]
116 );
117 assert_eq!(selected.into_json(), json!({"a":"one","c":null}));
118 }
119}