clickhouse_format/output/
json_compact_strings.rs1use core::marker::PhantomData;
2use std::collections::HashMap;
3
4use serde::de::DeserializeOwned;
5
6use crate::format_name::FormatName;
7
8use super::{json::JsonDataInfo, json_compact::JsonCompactOutput, Output, OutputResult};
9
10pub struct JsonCompactStringsOutput<T> {
11 phantom: PhantomData<T>,
12}
13impl<T> Default for JsonCompactStringsOutput<T> {
14 fn default() -> Self {
15 Self::new()
16 }
17}
18impl<T> JsonCompactStringsOutput<T> {
19 pub fn new() -> Self {
20 Self {
21 phantom: PhantomData,
22 }
23 }
24}
25pub type GeneralJsonCompactStringsOutput = JsonCompactStringsOutput<HashMap<String, String>>;
26
27impl<T> Output for JsonCompactStringsOutput<T>
28where
29 T: DeserializeOwned,
30{
31 type Row = T;
32 type Info = JsonDataInfo;
33
34 type Error = serde_json::Error;
35
36 fn format_name() -> FormatName {
37 FormatName::JsonCompactStrings
38 }
39
40 fn deserialize(&self, slice: &[u8]) -> OutputResult<Self::Row, Self::Info, Self::Error> {
41 JsonCompactOutput::new().deserialize_with::<String>(slice)
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 use std::{fs, path::PathBuf};
50
51 use crate::test_helpers::{TestStringsRow, TEST_STRINGS_ROW_1};
52
53 #[test]
54 fn simple() -> Result<(), Box<dyn std::error::Error>> {
55 let file_path = PathBuf::new().join("tests/files/JSONCompactStrings.json");
56 let content = fs::read_to_string(&file_path)?;
57
58 assert_eq!(
59 GeneralJsonCompactStringsOutput::format_name(),
60 file_path
61 .file_stem()
62 .unwrap()
63 .to_string_lossy()
64 .parse()
65 .unwrap()
66 );
67
68 let (rows, info) =
69 GeneralJsonCompactStringsOutput::new().deserialize(content.as_bytes())?;
70 assert_eq!(rows.first().unwrap().get("tuple1").unwrap(), "(1,'a')");
71 assert_eq!(info.rows, 2);
72
73 let (rows, info) =
74 JsonCompactStringsOutput::<TestStringsRow>::new().deserialize(content.as_bytes())?;
75 assert_eq!(rows.first().unwrap(), &*TEST_STRINGS_ROW_1);
76 assert_eq!(info.rows, 2);
77
78 Ok(())
79 }
80}