nu_cmd_extra/extra/bits/
xor.rs1use super::binary_op;
2use nu_engine::command_prelude::*;
3use nu_heavy_utils::Endian;
4
5#[derive(Clone)]
6pub struct BitsXor;
7
8impl Command for BitsXor {
9 fn name(&self) -> &str {
10 "bits xor"
11 }
12
13 fn signature(&self) -> Signature {
14 Signature::build("bits xor")
15 .input_output_types(vec![
16 (Type::Int, Type::Int),
17 (Type::Binary, Type::Binary),
18 (
19 Type::List(Box::new(Type::Int)),
20 Type::List(Box::new(Type::Int)),
21 ),
22 (
23 Type::List(Box::new(Type::Binary)),
24 Type::List(Box::new(Type::Binary)),
25 ),
26 ])
27 .allow_variants_without_examples(true)
28 .required(
29 "target",
30 SyntaxShape::OneOf(vec![SyntaxShape::Binary, SyntaxShape::Int]),
31 "Right-hand side of the operation.",
32 )
33 .param(Endian::flag())
34 .category(Category::Bits)
35 }
36
37 fn description(&self) -> &str {
38 "Performs bitwise xor for ints or binary values."
39 }
40
41 fn search_terms(&self) -> Vec<&str> {
42 vec!["logic xor"]
43 }
44
45 fn run(
46 &self,
47 engine_state: &EngineState,
48 stack: &mut Stack,
49 call: &Call,
50 input: PipelineData,
51 ) -> Result<PipelineData, ShellError> {
52 let head = call.head;
53 let target: Value = call.req(engine_state, stack, 0)?;
54 let endian = call
55 .get_flag::<Endian>(engine_state, stack, "endian")?
56 .unwrap_or_default();
57
58 if let PipelineData::Empty = input {
60 return Err(ShellError::PipelineEmpty { dst_span: head });
61 }
62
63 input.map(
64 move |value| binary_op(&value, &target, endian, |(l, r)| l ^ r, head),
65 engine_state.signals(),
66 )
67 }
68
69 fn examples(&self) -> Vec<Example<'_>> {
70 vec![
71 Example {
72 description: "Apply bits xor to two numbers",
73 example: "2 | bits xor 2",
74 result: Some(Value::test_int(0)),
75 },
76 Example {
77 description: "Apply bitwise xor to a list of numbers",
78 example: "[8 3 2] | bits xor 2",
79 result: Some(Value::test_list(vec![
80 Value::test_int(10),
81 Value::test_int(1),
82 Value::test_int(0),
83 ])),
84 },
85 Example {
86 description: "Apply bitwise xor to binary data",
87 example: "0x[ca fe] | bits xor 0x[ba be]",
88 result: Some(Value::test_binary(vec![0x70, 0x40])),
89 },
90 Example {
91 description: "Apply bitwise xor to binary data of varying lengths with specified endianness",
92 example: "0x[ca fe] | bits xor 0x[aa] --endian big",
93 result: Some(Value::test_binary(vec![0xca, 0x54])),
94 },
95 Example {
96 description: "Apply bitwise xor to input binary data smaller than the operand",
97 example: "0x[ff] | bits xor 0x[12 34 56] --endian little",
98 result: Some(Value::test_binary(vec![0xed, 0x34, 0x56])),
99 },
100 ]
101 }
102}
103
104#[cfg(test)]
105mod test {
106 use super::*;
107
108 #[test]
109 fn test_examples() -> nu_test_support::Result {
110 nu_test_support::test().examples(BitsXor)
111 }
112}