0

I'm trying to write an application that listens for keyboard input, detects barcode scans, and submits that data to an HTTP endpoint. For now, I'm struggling with the simple problem of capturing data from a scan. I've tried using the device_query package but struggled with very inaccurate data. inputbot is providing more accurate results, but I cannot figure out some basic issues with borrowing and accumulating data in a Vec.

use inputbot::KeybdKey;

fn main() {
    let mut chars = Vec::new();
    let c = ",".to_string();

    KeybdKey::bind_all(|event| {
        if event == KeybdKey::Numrow1Key || chars.first().unwrap() == "1" {
            // start collecting chars
            if event == KeybdKey::EnterKey {
                println!("{:?}", &chars);
                chars.retain(|event| event == &c);
            } else {
                chars.push(inputbot::from_keybd_key(event).unwrap().to_string());
            }
        } else {
            println!("Something... {:?}", event);
        }
    });

    inputbot::handle_input_events();
}

From here, I just get the compile error: the trait bound &mut Vec<String>: Copy is not satisfied. I've tried using move as well as collecting to a char Vec and a KeybdKey Vec, but it makes no difference. I've tried using Arc/Mutex as shown in this post, but it still errors out. It's unclear to me how this is a memory safety protection when my application is a single-threaded application with only one access to the chars variable at a time.

Error Message:

error[E0277]: the trait bound `&mut Vec<String>: Copy` is not satisfied in `[closure@src\main.rs:10:24: 22:6]`
   --> src\main.rs:10:5
    |
10  |       KeybdKey::bind_all(|event| {
    |  _____^^^^^^^^^^^^^^^^^^_-
    | |     |
    | |     within `[closure@src\main.rs:10:24: 22:6]`, the trait `Copy` is not implemented for `&mut Vec<String>`
11  | |         if event == KeybdKey::Numrow1Key || chars.first().unwrap() == "1" {
12  | |             // start collecting chars
13  | |             if event == KeybdKey::EnterKey {
...   |
21  | |         }
22  | |     });
    | |_____- within this `[closure@src\main.rs:10:24: 22:6]`
    |
    = note: `Copy` is implemented for `&std::vec::Vec<std::string::String>`, but not for `&mut std::vec::Vec<std::string::String>`
    = note: required because it appears within the type `[closure@src\main.rs:10:24: 22:6]`
note: required by a bound in `KeybdKey::bind_all`
tufelkinder
  • 1,176
  • 1
  • 15
  • 37
  • 1
    Can you add the full error message to the question? – Dogbert May 28 '22 at 21:39
  • The error has been added. – tufelkinder May 29 '22 at 03:37
  • 1
    [The function `bind_all`](https://github.com/obv-mikhail/InputBot/blob/2245b7ada826d159aabb1f16291115dd54d790b7/src/public.rs#L157) requires the closure to be `Fn(KeybdKey) + Send + Sync + Copy + 'static`. – kotatsuyaki May 29 '22 at 03:51
  • 1
    The `Copy` bound here is problematic. If the closure moves `Arc>>` into itself, then it is no longer a copyable closure (it's `Clone` but not `Copy`). I can't think of an elegant way to solve this. Is the `Copy` bound really necessary for the library? – kotatsuyaki May 29 '22 at 04:06
  • 1
    [I opened a PR](https://github.com/obv-mikhail/InputBot/pull/58) on the repository of InputBot as an attempt to fix this. – kotatsuyaki May 29 '22 at 06:01
  • @kotatsuyaki thank you! I appreciate you help me feel like I'm not going insane! – tufelkinder May 30 '22 at 05:42

0 Answers0