Skip to content

Commit

Permalink
printf: handle Array and Map (#26)
Browse files Browse the repository at this point in the history
Handle printing of "%v" with Array and Map objects.

Obviously this won't cover 100% of the cases, but it's better than
nothing :)

Signed-off-by: Flavio Castelli <fcastelli@suse.com>
  • Loading branch information
flavio committed Aug 6, 2021
1 parent 70307f7 commit 447f416
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
22 changes: 22 additions & 0 deletions src/print_verb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,28 @@ pub fn print(p: &FormatParams, typ: char, val: &Value) -> Result<String, PrintEr
}
_ => return Err(PrintError::UnableToFormat(val.clone(), typ)),
}),
Value::Array(ref a) => Ok(match typ {
'v' => {
let values: Vec<String> = a.iter().map(|v| printf_generic(p, v)).collect();
let res = format!("[{}]", values.join(" "));
printf_generic(p, res)
}
_ => return Err(PrintError::UnableToFormat(val.clone(), typ)),
}),
Value::Map(ref m) => Ok(match typ {
'v' => {
let values: Vec<String> = m
.iter()
.map(|(k, v)| {
let v_str = printf_generic(p, v);
format!("{}:{}", k, v_str)
})
.collect();
let res = format!("map[{}]", values.join(" "));
printf_generic(p, res)
}
_ => return Err(PrintError::UnableToFormat(val.clone(), typ)),
}),
_ => Err(PrintError::UnableToFormat(val.clone(), typ)),
}
}
Expand Down
37 changes: 37 additions & 0 deletions src/printf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ pub fn params_to_chars(params: &FormatParams) -> (char, char, char, char, char)

#[cfg(test)]
mod test {
use std::collections::HashMap;

use super::*;

#[test]
Expand Down Expand Up @@ -307,6 +309,41 @@ mod test {
assert_eq!(s, r"+101");
}

#[test]
fn test_sprintf_array() {
let values: Vec<Value> = vec!["hello".into(), "world".into()];
let s = sprintf("foo %v", &[Value::Array(values)]);
assert!(s.is_ok());
let s = s.unwrap();
assert_eq!(s, r"foo [hello world]");

let values: Vec<Value> = vec![42.into(), 100.into()];
let s = sprintf("foo %v", &[Value::Array(values)]);
assert!(s.is_ok());
let s = s.unwrap();
assert_eq!(s, r"foo [42 100]");
}

#[test]
fn test_sprintf_map() {
let mut values: HashMap<String, Value> = HashMap::new();
values.insert("hello".into(), "world".into());
values.insert("number".into(), 42.into());
let s = sprintf("foo %v", &[Value::Map(values)]);
assert!(s.is_ok());
let s = s.unwrap();
// The print order is unpredictable, we can't write
// a straight comparison
assert!(s == "foo map[number:42 hello:world]" || s == "foo map[hello:world number:42]");

let mut values: HashMap<String, Value> = HashMap::new();
values.insert("float".into(), 4.2.into());
let s = sprintf("%v", &[Value::Map(values)]);
assert!(s.is_ok());
let s = s.unwrap();
assert_eq!(s, r"map[float:4.2]");
}

#[test]
fn test_tokenize() {
let t = tokenize("foobar%6.2ffoobar");
Expand Down

0 comments on commit 447f416

Please sign in to comment.