From 2970d48d41bd922cf3301b30c805712a59a2a061 Mon Sep 17 00:00:00 2001 From: Devyn Cairns Date: Wed, 1 May 2024 15:29:33 -0700 Subject: [PATCH] Make `bytes build` accept integer values as individual bytes (#12685) # Description This creates an option for building binary data from byte integers. Previously I think you could only do this by formatting the integers to hex and using `decode hex`. One potentially confusing thing is that this is different from the `into binary` behavior. But since this doesn't support any of the other `into binary` behaviors, it might be okay. # User-Facing Changes - `bytes build` accepts single byte arguments as integers # Tests + Formatting Example added. # After Submitting - [ ] release notes --- crates/nu-command/src/bytes/build_.rs | 32 ++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/crates/nu-command/src/bytes/build_.rs b/crates/nu-command/src/bytes/build_.rs index 29c231b108..f6b1327621 100644 --- a/crates/nu-command/src/bytes/build_.rs +++ b/crates/nu-command/src/bytes/build_.rs @@ -24,14 +24,21 @@ impl Command for BytesBuild { } fn examples(&self) -> Vec { - vec![Example { - example: "bytes build 0x[01 02] 0x[03] 0x[04]", - description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]", - result: Some(Value::binary( - vec![0x01, 0x02, 0x03, 0x04], - Span::test_data(), - )), - }] + vec![ + Example { + example: "bytes build 0x[01 02] 0x[03] 0x[04]", + description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]", + result: Some(Value::binary( + vec![0x01, 0x02, 0x03, 0x04], + Span::test_data(), + )), + }, + Example { + example: "bytes build 255 254 253 252", + description: "Builds binary data from byte numbers", + result: Some(Value::test_binary(vec![0xff, 0xfe, 0xfd, 0xfc])), + }, + ] } fn run( @@ -46,8 +53,17 @@ impl Command for BytesBuild { let eval_expression = get_eval_expression(engine_state); eval_expression(engine_state, stack, expr) })? { + let val_span = val.span(); match val { Value::Binary { mut val, .. } => output.append(&mut val), + Value::Int { val, .. } => { + let byte: u8 = val.try_into().map_err(|_| ShellError::IncorrectValue { + msg: format!("{val} is out of range for byte"), + val_span, + call_span: call.head, + })?; + output.push(byte); + } // Explicitly propagate errors instead of dropping them. Value::Error { error, .. } => return Err(*error), other => {