How I can use the on_message function in scope inside the main function?

Hi

How I can use the on_message function in scope inside the main function and allow main to access everything inside the on_message function. Currently I cannot use the function inside the main function.

extern crate mosquitto_client as mosq;
use mosq::Mosquitto;

fn main() {
    let m = on_connect();
    
    let bonzo = m.subscribe("bonzo/#",0).expect("can't subscribe to bonzo");
    let frodo = m.subscribe("frodo/#",0).expect("can't subscribe to frodo");
    
    m.publish("bonzo/baggins", "hi".as_bytes(), 1, false).unwrap();
    m.publish("frodo/#", "hi".as_bytes(), 1, false).unwrap();
    
    on_message();
        
    m.loop_until_disconnect(200).expect("broken loop");
}

fn on_connect() -> (mosq::Mosquitto) {
    let m = Mosquitto::new("test");
    m.connect("broker.hivemq.com",1883).expect("can't connect");
    m
}

fn on_message() {
    let mut mc = m.callbacks(());
    mc.on_message(|_,msg| {
        if ! msg.retained() {
            if bonzo.matches(&msg) {
                println!("bonzo {:?}",msg);
            } else
            if frodo.matches(&msg) {
                println!("frodo {:?}",msg);
            }
        }
    });
}

Thanks

Please use the edit post feature instead of posting a new topic.

You can give on_message a borrow of the m variable like this:

fn on_message(m: &mut mosq::Mosquitto) {
    ...
}
fn main() {
    ...
    on_message(&mut m);
    ...
}

Do I need to edit any code from the on_message function?

That depends on what you want to do.

I want to print out the results of the callback in on_message function.

You already have prints inside the callback. Does it not work if you pass m as an argument?

I get these errors.

Please post your errors in a code block like this:

```
// your error goes here
```

You will need to give on_message access to the values. You can do this by passing them as an argument or by making on_message a function on a struct that has the bonzo and frodo variables in a field.

Ok can you show me how to this using both of the methods.

Thanks

Please take a look at the page on functions in the rust book here. For the second approach, you can read chapter five, which starts on this page.

Is there a way without having to give on_message access to these values?

Compiling practise v0.1.0 (/home/pi/rust/practise)
error[E0308]: mismatched types
  --> src/main.rs:13:24
   |
13 |     on_message(&mut m, &mut bonzo, &mut frodo);
   |                        ^^^^^^^^^^ expected `str`, found struct `mosq::TopicMatcher`
   |
   = note: expected mutable reference `&mut str`
              found mutable reference `&mut mosq::TopicMatcher<'_>`

error[E0308]: mismatched types
  --> src/main.rs:13:36
   |
13 |     on_message(&mut m, &mut bonzo, &mut frodo);
   |                                    ^^^^^^^^^^ expected `str`, found struct `mosq::TopicMatcher`
   |
   = note: expected mutable reference `&mut str`
              found mutable reference `&mut mosq::TopicMatcher<'_>`

error[E0277]: expected a `std::ops::Fn<(char,)>` closure, found `mosq::MosqMessage`
  --> src/main.rs:28:30
   |
28 |             if bonzo.matches(&msg) {
   |                              ^^^^ expected an `Fn<(char,)>` closure, found `mosq::MosqMessage`
   |
   = help: the trait `std::ops::Fn<(char,)>` is not implemented for `mosq::MosqMessage`
   = note: required because of the requirements on the impl of `std::ops::FnOnce<(char,)>` for `&mosq::MosqMessage`
   = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&mosq::MosqMessage`

error[E0308]: mismatched types
  --> src/main.rs:28:16
   |
28 |             if bonzo.matches(&msg) {
   |                ^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::str::Matches`
   |
   = note: expected type `bool`
            found struct `std::str::Matches<'_, &mosq::MosqMessage>`

error[E0277]: expected a `std::ops::Fn<(char,)>` closure, found `mosq::MosqMessage`
  --> src/main.rs:31:30
   |
31 |             if frodo.matches(&msg) {
   |                              ^^^^ expected an `Fn<(char,)>` closure, found `mosq::MosqMessage`
   |
   = help: the trait `std::ops::Fn<(char,)>` is not implemented for `mosq::MosqMessage`
   = note: required because of the requirements on the impl of `std::ops::FnOnce<(char,)>` for `&mosq::MosqMessage`
   = note: required because of the requirements on the impl of `std::str::pattern::Pattern<'_>` for `&mosq::MosqMessage`

error[E0308]: mismatched types
  --> src/main.rs:31:16
   |
31 |             if frodo.matches(&msg) {
   |                ^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::str::Matches`
   |
   = note: expected type `bool`
            found struct `std::str::Matches<'_, &mosq::MosqMessage>`

error: aborting due to 6 previous errors

So how can fix these errors. What would be the correct types?

The error message tells you: It's mosq::TopicMatcher<'_>. You might want to pass it by value instead of as a mutable reference.

Are you asking if there's a way to give on_message access to the values without giving on_message access to the values?

yes

The answer is no. If you give on_message access to the values, you've given on_message access to the values.

   Compiling practise v0.1.0 (/home/pi/rust/practise)
error[E0502]: cannot borrow `m` as mutable because it is also borrowed as immutable
  --> src/main.rs:13:16
   |
7  |     let mut bonzo = m.subscribe("bonzo/#",0).expect("can't subscribe to bonzo");
   |                     - immutable borrow occurs here
...
13 |     on_message(&mut m, &mut bonzo, &mut frodo);
   |                ^^^^^^  ---------- immutable borrow later used here
   |                |
   |                mutable borrow occurs here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0502`.
error: could not compile `practise`.

How do I fix this error?

It looks like you should be using immutable references instead.

How do declare an immutable reference?

With & instead of &mut. I strongly recommend you read the Rust book. Chapter four talks about this topic: link.