Skip to main content

vix_format_tool/
lib.rs

1//! Reformat the selection (or buffer) within one data format: pretty-print or
2//! minify JSON, and canonicalize YAML and TOML.
3//!
4//! Each function parses the text into a generic value and re-serializes it, so
5//! the document is normalized (consistent indentation, key handling, quoting)
6//! without changing its meaning. Used by the Tools → Format menu via
7//! `App::transform_selection_or_buffer_try`.
8
9#![warn(clippy::pedantic)]
10#![forbid(unsafe_code)]
11#![deny(missing_docs)]
12
13/// Pretty-print JSON with two-space indentation.
14///
15/// # Errors
16/// Returns an error when the input is not valid JSON.
17pub fn json_pretty(input: &str) -> Result<String, String> {
18    let v: serde_json::Value = serde_json::from_str(input).map_err(|e| e.to_string())?;
19    serde_json::to_string_pretty(&v).map_err(|e| e.to_string())
20}
21
22/// Minify JSON to its most compact single-line form.
23///
24/// # Errors
25/// Returns an error when the input is not valid JSON.
26pub fn json_minify(input: &str) -> Result<String, String> {
27    let v: serde_json::Value = serde_json::from_str(input).map_err(|e| e.to_string())?;
28    serde_json::to_string(&v).map_err(|e| e.to_string())
29}
30
31/// Canonicalize YAML (re-emit with consistent formatting).
32///
33/// # Errors
34/// Returns an error when the input is not valid YAML.
35pub fn yaml_format(input: &str) -> Result<String, String> {
36    let v: serde_norway::Value = serde_norway::from_str(input).map_err(|e| e.to_string())?;
37    serde_norway::to_string(&v).map_err(|e| e.to_string())
38}
39
40/// Canonicalize TOML (re-emit pretty-printed).
41///
42/// # Errors
43/// Returns an error when the input is not valid TOML, or is not a table.
44pub fn toml_format(input: &str) -> Result<String, String> {
45    let v: toml::Value = toml::from_str(input).map_err(|e| e.to_string())?;
46    toml::to_string_pretty(&v).map_err(|e| e.to_string())
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn json_pretty_indents() {
55        assert_eq!(json_pretty(r#"{"a":1}"#).unwrap(), "{\n  \"a\": 1\n}");
56    }
57
58    #[test]
59    fn json_minify_compacts() {
60        assert_eq!(json_minify("{\n  \"a\": 1\n}").unwrap(), r#"{"a":1}"#);
61    }
62
63    #[test]
64    fn json_rejects_bad_input() {
65        assert!(json_pretty("{nope}").is_err());
66        assert!(json_minify("{nope}").is_err());
67    }
68
69    #[test]
70    fn yaml_roundtrips() {
71        let out = yaml_format("a:    1\nb: 2\n").unwrap();
72        assert!(out.contains("a: 1"), "got: {out}");
73        assert!(yaml_format("a: [unclosed").is_err());
74    }
75
76    #[test]
77    fn toml_roundtrips() {
78        let out = toml_format("a=1\nb=2\n").unwrap();
79        assert!(out.contains("a = 1"), "got: {out}");
80        assert!(toml_format("= bad").is_err());
81    }
82}