use serde::Serialize;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum OutputFormat {
#[default]
Json,
JsonCompact,
Toon,
}
pub fn format_output<T: Serialize>(value: &T, format: OutputFormat) -> Result<String, String> {
match format {
OutputFormat::Json => serde_json::to_string_pretty(value).map_err(|e| e.to_string()),
OutputFormat::JsonCompact => serde_json::to_string(value).map_err(|e| e.to_string()),
OutputFormat::Toon => format_toon(value),
}
}
#[cfg(feature = "toon")]
fn format_toon<T: Serialize>(value: &T) -> Result<String, String> {
let json = serde_json::to_value(value).map_err(|e| e.to_string())?;
Ok(toon::encode(&json, None))
}
#[cfg(not(feature = "toon"))]
fn format_toon<T: Serialize>(value: &T) -> Result<String, String> {
serde_json::to_string_pretty(value).map_err(|e| e.to_string())
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
use crate::vfs::types::DirEntry;
#[test]
fn test_json_format() {
let entry = DirEntry {
name: "hello.txt".to_string(),
path: "/hello.txt".to_string(),
is_dir: false,
size: Some(42),
modified: None,
permissions: None,
is_symlink: false,
};
let out = format_output(&entry, OutputFormat::Json).expect("json");
assert!(out.contains("hello.txt"));
assert!(out.contains('\n')); }
#[test]
fn test_json_compact_format() {
let entry = DirEntry {
name: "hello.txt".to_string(),
path: "/hello.txt".to_string(),
is_dir: false,
size: Some(42),
modified: None,
permissions: None,
is_symlink: false,
};
let out = format_output(&entry, OutputFormat::JsonCompact).expect("json compact");
assert!(out.contains("hello.txt"));
assert!(!out.contains('\n')); }
#[cfg(feature = "toon")]
#[test]
fn test_toon_format() {
let entries = vec![
DirEntry {
name: "a.rs".to_string(),
path: "/a.rs".to_string(),
is_dir: false,
size: Some(100),
modified: None,
permissions: None,
is_symlink: false,
},
DirEntry {
name: "b.rs".to_string(),
path: "/b.rs".to_string(),
is_dir: false,
size: Some(200),
modified: None,
permissions: None,
is_symlink: false,
},
];
let out = format_output(&entries, OutputFormat::Toon).expect("toon");
let json = format_output(&entries, OutputFormat::Json).expect("json");
assert!(
out.len() <= json.len(),
"TOON should be <= JSON for tabular data"
);
}
}