gq_core/data/
format.rs

1use std::{io, string::FromUtf8Error};
2
3use crate::{data::DataType, format::Indentation};
4use colored_json::ColoredFormatter;
5use serde::Serialize;
6use serde_json::{
7    ser::{CompactFormatter, Formatter, PrettyFormatter},
8    Serializer, Value,
9};
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum Error {
14    #[error("error while formatting json: {0}")]
15    Json(#[from] serde_json::Error),
16
17    #[error("error while formatting yaml: {0}")]
18    Yaml(#[from] serde_yaml::Error),
19
20    #[error("IO error while formatting: {0}")]
21    Io(#[from] io::Error),
22
23    #[error("error while creating String from UTF-8 bytes: {0}")]
24    FromUtf8(#[from] FromUtf8Error),
25}
26
27pub type Result<T> = std::result::Result<T, Error>;
28
29impl DataType {
30    pub fn pretty_format(&self, value: &Value, indentation: Indentation) -> Result<String> {
31        let mut buf = Vec::new();
32        self.pretty_format_to_writer(&mut buf, value, indentation)?;
33        Ok(String::from_utf8(buf)?)
34    }
35
36    pub fn pretty_format_to_writer<W: io::Write>(
37        &self,
38        writer: &mut W,
39        value: &Value,
40        indentation: Indentation,
41    ) -> Result<()> {
42        match self {
43            DataType::Json => serialize_json(writer, value, indentation),
44            // TODO: pretty yaml is not supported
45            DataType::Yaml => Ok(serde_yaml::to_writer(writer, value)?),
46        }
47    }
48}
49
50impl DataType {
51    pub fn pretty_format_colored(&self, value: &Value, indentation: Indentation) -> Result<String> {
52        let mut buf = Vec::new();
53        self.pretty_format_colored_to_writer(&mut buf, value, indentation)?;
54        Ok(String::from_utf8(buf)?)
55    }
56
57    pub fn pretty_format_colored_to_writer<W: io::Write>(
58        &self,
59        writer: &mut W,
60        value: &Value,
61        indentation: Indentation,
62    ) -> Result<()> {
63        match self {
64            DataType::Json => serialize_colored_json(value, writer, indentation),
65            // TODO: colored yaml is not supported
66            DataType::Yaml => Ok(serde_yaml::to_writer(writer, value)?),
67        }
68    }
69}
70
71fn serialize_json<W: io::Write>(
72    writer: &mut W,
73    value: &Value,
74    indentation: Indentation,
75) -> Result<()> {
76    match indentation {
77        Indentation::None => {
78            let formatter = CompactFormatter {};
79            serialize_json_with_formatter(value, writer, formatter)
80        }
81        Indentation::Spaces(_) | Indentation::Tabs(_) => {
82            let indentation_fmt = indentation.to_string();
83            let formatter = PrettyFormatter::with_indent(indentation_fmt.as_bytes());
84            serialize_json_with_formatter(value, writer, formatter)
85        }
86    }
87}
88
89fn serialize_colored_json<W: io::Write>(
90    value: &Value,
91    writer: &mut W,
92    indentation: Indentation,
93) -> Result<()> {
94    let indentation_fmt = indentation.to_string();
95    match indentation {
96        Indentation::None => {
97            let formatter = ColoredFormatter::new(CompactFormatter {});
98            serialize_json_with_formatter(value, writer, formatter)
99        }
100        Indentation::Spaces(_) | Indentation::Tabs(_) => {
101            let formatter =
102                ColoredFormatter::new(PrettyFormatter::with_indent(indentation_fmt.as_bytes()));
103            serialize_json_with_formatter(value, writer, formatter)
104        }
105    }
106}
107
108fn serialize_json_with_formatter<W: io::Write, F: Formatter>(
109    value: &Value,
110    writer: &mut W,
111    formatter: F,
112) -> Result<()> {
113    let mut serializer = Serializer::with_formatter(writer, formatter);
114    Ok(value.serialize(&mut serializer)?)
115}