synwire_core/vfs/
output.rs1use serde::Serialize;
15
16#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
18#[non_exhaustive]
19pub enum OutputFormat {
20 #[default]
22 Json,
23 JsonCompact,
25 Toon,
29}
30
31pub fn format_output<T: Serialize>(value: &T, format: OutputFormat) -> Result<String, String> {
37 match format {
38 OutputFormat::Json => serde_json::to_string_pretty(value).map_err(|e| e.to_string()),
39 OutputFormat::JsonCompact => serde_json::to_string(value).map_err(|e| e.to_string()),
40 OutputFormat::Toon => format_toon(value),
41 }
42}
43
44#[cfg(feature = "toon")]
45fn format_toon<T: Serialize>(value: &T) -> Result<String, String> {
46 let json = serde_json::to_value(value).map_err(|e| e.to_string())?;
47 Ok(toon::encode(&json, None))
48}
49
50#[cfg(not(feature = "toon"))]
51fn format_toon<T: Serialize>(value: &T) -> Result<String, String> {
52 serde_json::to_string_pretty(value).map_err(|e| e.to_string())
54}
55
56#[cfg(test)]
57#[allow(clippy::expect_used)]
58mod tests {
59 use super::*;
60 use crate::vfs::types::DirEntry;
61
62 #[test]
63 fn test_json_format() {
64 let entry = DirEntry {
65 name: "hello.txt".to_string(),
66 path: "/hello.txt".to_string(),
67 is_dir: false,
68 size: Some(42),
69 modified: None,
70 permissions: None,
71 is_symlink: false,
72 };
73 let out = format_output(&entry, OutputFormat::Json).expect("json");
74 assert!(out.contains("hello.txt"));
75 assert!(out.contains('\n')); }
77
78 #[test]
79 fn test_json_compact_format() {
80 let entry = DirEntry {
81 name: "hello.txt".to_string(),
82 path: "/hello.txt".to_string(),
83 is_dir: false,
84 size: Some(42),
85 modified: None,
86 permissions: None,
87 is_symlink: false,
88 };
89 let out = format_output(&entry, OutputFormat::JsonCompact).expect("json compact");
90 assert!(out.contains("hello.txt"));
91 assert!(!out.contains('\n')); }
93
94 #[cfg(feature = "toon")]
95 #[test]
96 fn test_toon_format() {
97 let entries = vec![
98 DirEntry {
99 name: "a.rs".to_string(),
100 path: "/a.rs".to_string(),
101 is_dir: false,
102 size: Some(100),
103 modified: None,
104 permissions: None,
105 is_symlink: false,
106 },
107 DirEntry {
108 name: "b.rs".to_string(),
109 path: "/b.rs".to_string(),
110 is_dir: false,
111 size: Some(200),
112 modified: None,
113 permissions: None,
114 is_symlink: false,
115 },
116 ];
117 let out = format_output(&entries, OutputFormat::Toon).expect("toon");
118 let json = format_output(&entries, OutputFormat::Json).expect("json");
120 assert!(
121 out.len() <= json.len(),
122 "TOON should be <= JSON for tabular data"
123 );
124 }
125}