diff --git a/crates/nu-command/src/strings/char_.rs b/crates/nu-command/src/strings/char_.rs index fe755c2912..a6125b8acc 100644 --- a/crates/nu-command/src/strings/char_.rs +++ b/crates/nu-command/src/strings/char_.rs @@ -192,6 +192,11 @@ impl Command for Char { example: r#"char -u 1f378"#, result: Some(Value::test_string("\u{1f378}")), }, + Example { + description: "Output a character from an integer", + example: r#"char -u 0x61"#, + result: Some(Value::test_string("a")), + }, Example { description: "Output multi-byte Unicode character", example: r#"char -u 1F468 200D 1F466 200D 1F466"#, @@ -235,8 +240,8 @@ impl Command for Char { .into_pipeline_data(engine_state.ctrlc.clone())); } // handle -u flag - let args: Vec = call.rest(engine_state, stack, 0)?; if call.has_flag("unicode") { + let args: Vec = call.rest(engine_state, stack, 0)?; if args.is_empty() { return Err(ShellError::MissingParameter( "missing at least one unicode character".into(), @@ -249,10 +254,11 @@ impl Command for Char { .positional_nth(i) .expect("Unexpected missing argument") .span; - multi_byte.push(string_to_unicode_char(arg, &span)?) + multi_byte.push(value_to_unicode_char(arg, &span)?) } Ok(Value::string(multi_byte, call_span).into_pipeline_data()) } else { + let args: Vec = call.rest(engine_state, stack, 0)?; if args.is_empty() { return Err(ShellError::MissingParameter( "missing name of the character".into(), @@ -274,10 +280,14 @@ impl Command for Char { } } -fn string_to_unicode_char(s: &str, t: &Span) -> Result { - let decoded_char = u32::from_str_radix(s, 16) - .ok() - .and_then(std::char::from_u32); +fn value_to_unicode_char(value: &Value, t: &Span) -> Result { + let decoded_char = match *value { + Value::String { ref val, .. } => u32::from_str_radix(val, 16) + .ok() + .and_then(std::char::from_u32), + Value::Int { val, .. } => val.try_into().ok().and_then(std::char::from_u32), + _ => return Err(ShellError::TypeMismatch("string or int".to_owned(), *t)), + }; if let Some(ch) = decoded_char { Ok(ch)