Skip to content

Commit

Permalink
flake-info: Adapt RFC-166 style (#749)
Browse files Browse the repository at this point in the history
* flake-info: Adapt RFC-166 style

* flake-info: Properly escape attrset keys

* flake-info: Stop owning values for pretty-printing
  • Loading branch information
dasJ authored Apr 8, 2024
1 parent 7081483 commit 0f14890
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 14 deletions.
2 changes: 1 addition & 1 deletion flake-info/src/data/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ impl Serialize for DocValue {
md.to_owned()
}))
}
DocValue::Value(v) => serializer.serialize_str(&print_value(v.to_owned())),
DocValue::Value(v) => serializer.serialize_str(&print_value(v)),
}
}
}
Expand Down
111 changes: 98 additions & 13 deletions flake-info/src/data/prettyprint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,24 @@ impl Display for Indent {
}
}

pub fn print_value(value: Value) -> String {
pub fn print_value(value: &Value) -> String {
print_value_indent(value, Indent(0))
}

fn print_value_indent(value: Value, indent: Indent) -> String {
/// Formats an attrset key by adding quotes when necessary
fn format_attrset_key(key: &str) -> String {
if key.contains("/")
|| key.contains(" ")
|| key.is_empty()
|| (b'0'..=b'9').contains(&key.as_bytes()[0])
{
format!("{:?}", key)
} else {
key.to_string()
}
}

fn print_value_indent(value: &Value, indent: Indent) -> String {
match value {
Value::Null => "null".to_owned(),
Value::Bool(b) => format!("{}", b),
Expand All @@ -44,6 +57,14 @@ fn print_value_indent(value: Value, indent: Indent) -> String {
if a.is_empty() {
return "[ ]".to_owned();
}
if a.len() == 1 {
// Return early if the wrapped value fits on one line
let val = print_value(a.first().unwrap());
if !val.contains("\n") {
return format!("[ {} ]", val);
}
}

let items = a
.into_iter()
.map(|v| print_value_indent(v, indent.next()))
Expand All @@ -63,9 +84,26 @@ fn print_value_indent(value: Value, indent: Indent) -> String {
if o.is_empty() {
return "{ }".to_owned();
}
if o.len() == 1 {
// Return early if the wrapped value fits on one line
let val = print_value(o.values().next().unwrap());
if !val.contains("\n") {
return format!(
"{{ {} = {}; }}",
format_attrset_key(o.keys().next().unwrap()),
val
);
}
}
let items = o
.into_iter()
.map(|(k, v)| format!("{} = {}", k, print_value_indent(v, indent.next())))
.map(|(k, v)| {
format!(
"{} = {}",
format_attrset_key(&k),
print_value_indent(v, indent.next())
)
})
.collect::<Vec<_>>()
.join(&format!(";\n{}", indent.next()));

Expand All @@ -90,7 +128,7 @@ mod tests {
#[test]
fn test_string() {
let json = json!("Hello World");
assert_eq!(print_value(json), "\"Hello World\"");
assert_eq!(print_value(&json), "\"Hello World\"");
}

#[test]
Expand All @@ -101,7 +139,7 @@ World
!!!"#
);
assert_eq!(
print_value(json),
print_value(&json),
r#"''
Hello
World
Expand All @@ -113,26 +151,46 @@ World
#[test]
fn test_num() {
let json = json!(1);
assert_eq!(print_value(json), "1");
assert_eq!(print_value(&json), "1");
}

#[test]
fn test_bool() {
let json = json!(true);
assert_eq!(print_value(json), "true");
assert_eq!(print_value(&json), "true");
}

#[test]
fn test_empty_list() {
let json = json!([]);
assert_eq!(print_value(json), "[ ]");
assert_eq!(print_value(&json), "[ ]");
}

#[test]
fn test_list_one_item() {
let json = json!([1]);
assert_eq!(print_value(&json), "[ 1 ]");
}

#[test]
fn test_list_one_multiline_item() {
let json = json!(["first line\nsecond line"]);
assert_eq!(
print_value(&json),
r#"[
''
first line
second line
''
]"#
);
}

#[test]
fn test_filled_list() {
let json = json!([1, "hello", true, null]);
assert_eq!(
print_value(json),
print_value(&json),
r#"[
1
"hello"
Expand All @@ -145,15 +203,42 @@ World
#[test]
fn test_empty_set() {
let json = json!({});
assert_eq!(print_value(json), "{ }");
assert_eq!(print_value(&json), "{ }");
}

#[test]
fn test_set_one_item() {
let json = json!({ "hello": "world" });
assert_eq!(print_value(&json), "{ hello = \"world\"; }");
}

#[test]
fn test_set_number_key() {
let json = json!({ "1hello": "world" });
assert_eq!(print_value(&json), "{ \"1hello\" = \"world\"; }");
}

#[test]
fn test_set_one_multiline_item() {
let json = json!({ "hello": "pretty\nworld" });
assert_eq!(
print_value(&json),
"{
hello = ''
pretty
world
'';
}"
);
}

#[test]
fn test_filled_set() {
let json = json!({"hello": "world"});
let json = json!({"hello": "world", "another": "test"});
assert_eq!(
print_value(json),
print_value(&json),
"{
another = \"test\";
hello = \"world\";
}"
);
Expand All @@ -176,7 +261,7 @@ World
]);

assert_eq!(
print_value(json),
print_value(&json),
r#"[
"HDMI-0"
{
Expand Down

0 comments on commit 0f14890

Please sign in to comment.