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
//! Sheeter is a data file conversion library and CLI tool.
//!
//! This crate provides functions to convert between CSV and JSON formats.
//! It is designed to be small, fast, and portable, suitable for use on
//! low-end devices such as Android phones. The core idea is simple: take
//! data in one format, understand its structure, and emit it in another
//! format without unnecessary overhead.
//!
//! # Examples
//!
//! Convert CSV to JSON:
//!
//! ```
//! use sheeter_engine::csv_to_json;
//!
//! let csv = "name,age\nAlice,30\nBob,25";
//! let json = csv_to_json(csv).unwrap();
//! assert_eq!(json, r#"[{"name":"Alice","age":"30"},{"name":"Bob","age":"25"}]"#);
//! ```
//!
//! Convert JSON to CSV:
//!
//! ```
//! use sheeter_engine::json_to_csv;
//!
//! let json = r#"[{"name":"Alice","age":"30"},{"name":"Bob","age":"25"}]"#;
//! let csv = json_to_csv(json).unwrap();
//! assert_eq!(csv, "name,age\nAlice,30\nBob,25\n");
//! ```
use Cursor;
/// Converts a CSV string into a JSON array of objects.
///
/// CSV (Comma-Separated Values) is a simple tabular format where each line is a
/// row and columns are separated by commas. JSON (JavaScript Object Notation) is
/// a hierarchical data format. This function reads the first row of the CSV as
/// the header (column names) and each subsequent row as a data record. It then
/// builds a JSON array where each element is an object mapping header names to
/// the corresponding cell values as strings. This is useful for feeding CSV data
/// into JSON-based systems or APIs, or for further processing with JSON tools.
///
/// Duplicate header names are rejected because they would silently overwrite
/// data in the resulting JSON objects. All cells are represented as strings in
/// the JSON output; type information (numbers, booleans) is not inferred.
///
/// # Errors
///
/// Returns an error if the CSV is malformed (e.g., inconsistent number of columns),
/// if a header name appears more than once, or if JSON serialization fails (which
/// is unlikely for simple string maps).
///
/// # Examples
///
/// Basic conversion:
///
/// ```
/// use sheeter_engine::csv_to_json;
///
/// let csv = "name,age\nAlice,30\nBob,25";
/// let json = csv_to_json(csv).unwrap();
/// assert_eq!(json, r#"[{"name":"Alice","age":"30"},{"name":"Bob","age":"25"}]"#);
/// ```
///
/// Single column:
///
/// ```
/// use sheeter_engine::csv_to_json;
///
/// let csv = "id\n1\n2\n3";
/// let json = csv_to_json(csv).unwrap();
/// assert_eq!(json, r#"[{"id":"1"},{"id":"2"},{"id":"3"}]"#);
/// ```
///
/// Duplicate headers are rejected:
///
/// ```
/// use sheeter_engine::csv_to_json;
///
/// assert!(csv_to_json("a,a\n1,2").is_err());
/// ```
/// Converts a JSON array of objects into a CSV string.
///
/// JSON arrays of objects are a common way to represent tabular data. This function
/// takes such a JSON string and produces a CSV string. The CSV header row is the
/// union of all keys across all objects, in the order they first appear; if a key
/// is missing in a given object, the corresponding cell is left empty. Values are
/// converted to their string representation: strings are written as-is (without
/// quotes), numbers and booleans use their JSON literal forms, and null becomes
/// an empty cell. Nested objects and arrays cannot be represented losslessly in
/// flat CSV and cause an error, ensuring round-trips never silently corrupt data.
///
/// # Errors
///
/// Returns an error if the JSON is not a valid array of objects, if any value is
/// a nested object or array, or if CSV writing fails (e.g., due to I/O errors on
/// the internal buffer).
///
/// # Examples
///
/// Basic conversion:
///
/// ```
/// use sheeter_engine::json_to_csv;
///
/// let json = r#"[{"name":"Alice","age":"30"},{"name":"Bob","age":"25"}]"#;
/// let csv = json_to_csv(json).unwrap();
/// assert_eq!(csv, "name,age\nAlice,30\nBob,25\n");
/// ```
///
/// With numbers and booleans:
///
/// ```
/// use sheeter_engine::json_to_csv;
///
/// let json = r#"[{"id":1,"active":true},{"id":2,"active":false}]"#;
/// let csv = json_to_csv(json).unwrap();
/// assert_eq!(csv, "id,active\n1,true\n2,false\n");
/// ```
///
/// Extra keys in later objects are preserved:
///
/// ```
/// use sheeter_engine::json_to_csv;
///
/// let json = r#"[{"a":1},{"a":2,"b":3}]"#;
/// assert_eq!(json_to_csv(json).unwrap(), "a,b\n1,\n2,3\n");
/// ```
///
/// Nested values are rejected:
///
/// ```
/// use sheeter_engine::json_to_csv;
///
/// assert!(json_to_csv(r#"[{"a":{"nested":true}}]"#).is_err());
/// ```