add unicode to char command to print any unicode character (#2709)

* parsing unicode literal strings into chars

* refactored code to use -u option

* nudge ci
This commit is contained in:
Darren Schroeder 2020-10-28 09:08:09 -05:00 committed by GitHub
parent 8229af7591
commit 46d1938f5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,6 +9,7 @@ pub struct Char;
#[derive(Deserialize)] #[derive(Deserialize)]
struct CharArgs { struct CharArgs {
name: Tagged<String>, name: Tagged<String>,
unicode: bool,
} }
#[async_trait] #[async_trait]
@ -18,11 +19,13 @@ impl WholeStreamCommand for Char {
} }
fn signature(&self) -> Signature { fn signature(&self) -> Signature {
Signature::build("ansi").required( Signature::build("ansi")
"character", .required(
SyntaxShape::Any, "character",
"the name of the character to output", SyntaxShape::Any,
) "the name of the character to output",
)
.switch("unicode", "unicode string i.e. 1f378", Some('u'))
} }
fn usage(&self) -> &str { fn usage(&self) -> &str {
@ -45,6 +48,11 @@ impl WholeStreamCommand for Char {
UntaggedValue::string("\u{2261}").into(), UntaggedValue::string("\u{2261}").into(),
]), ]),
}, },
Example {
description: "Output unicode character",
example: r#"char -u 1f378"#,
result: Some(vec![Value::from("\u{1f378}")]),
},
] ]
} }
@ -53,24 +61,44 @@ impl WholeStreamCommand for Char {
args: CommandArgs, args: CommandArgs,
registry: &CommandRegistry, registry: &CommandRegistry,
) -> Result<OutputStream, ShellError> { ) -> Result<OutputStream, ShellError> {
let (CharArgs { name }, _) = args.process(&registry).await?; let (CharArgs { name, unicode }, _) = args.process(&registry).await?;
let special_character = str_to_character(&name.item); if unicode {
let decoded_char = string_to_unicode_char(&name.item);
if let Some(output) = special_character { if let Some(output) = decoded_char {
Ok(OutputStream::one(ReturnSuccess::value( Ok(OutputStream::one(ReturnSuccess::value(
UntaggedValue::string(output).into_value(name.tag()), UntaggedValue::string(output).into_value(name.tag()),
))) )))
} else {
Err(ShellError::labeled_error(
"error decoding unicode character",
"error decoding unicode character",
name.tag(),
))
}
} else { } else {
Err(ShellError::labeled_error( let special_character = str_to_character(&name.item);
"Unknown character", if let Some(output) = special_character {
"unknown character", Ok(OutputStream::one(ReturnSuccess::value(
name.tag(), UntaggedValue::string(output).into_value(name.tag()),
)) )))
} else {
Err(ShellError::labeled_error(
"error finding named character",
"error finding named character",
name.tag(),
))
}
} }
} }
} }
fn string_to_unicode_char(s: &str) -> Option<char> {
u32::from_str_radix(s, 16)
.ok()
.and_then(std::char::from_u32)
}
fn str_to_character(s: &str) -> Option<String> { fn str_to_character(s: &str) -> Option<String> {
match s { match s {
"newline" | "enter" | "nl" => Some("\n".into()), "newline" | "enter" | "nl" => Some("\n".into()),