Earlier I had a Sync + Send trait SyncMessenger:
trait Messenger {
fn send_message(&self, user_id: UserId, text: &str);
}
trait SyncMessenger: Messenger + Sync + Send {}
It's implementation:
pub struct DiscordMessenger {
discord: Arc<Discord>, // (Discord is Sync and Send already)
}
impl Messenger for DiscordMessenger {
fn send_message(&self, user_id: UserId, text: &str) {
self.discord.send_message(user_id, text, false);
}
}
impl SyncMessenger for DiscordMessenger {}
And using it:
struct Bot {
messenger: Arc<SyncMessenger>,
}
impl Bot {
pub fn new() -> Bot {
Bot { messenger: Arc::new(DiscordMessenger::new()) }
}
fn messenger(&self) -> Arc<SyncMessenger> {
self.messenger.clone()
}
}
struct PingCommand {
fn fire(&mut self, bot: &mut Bot) {
bot.messenger().send_message(UserId(0), "Pong");
}
}
Everything worked fine. Now I want to implement TestMessenger which does not really send a message through a network but toggles a flag in Self instead:
#[cfg(test)]
struct TestMessenger {
pub message_sent: bool,
}
impl Messenger for TestMessenger {
fn send_message(&mut self, user_id: UserId, text: &str) { // we have `&mut self` here
self.message_sent = true;
}
}
So I need to change send_message(&self) to send_message(&mut self) everywhere (in traits and in implementations). I did that but after I can't compile my user code:
struct PingCommand {
fn fire(&mut self, bot: &mut Bot) {
bot.messenger().send_message(UserId(0), "Pong");
}
}
Gives error:
|
12 | let _ = bot.messenger().send_message(UserId(0),
| ^^^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to previous error
I have found something that works but it looks very ugly to me (and requires unwrap() which I would like to avoid):
let _ = Arc::get_mut(&mut bot.messenger()).unwrap().send_message(UserId(0),
So the question here is how to do that as much simple as possible, without unwrap()s, static methods like Arc::get_mut? Why simple fn messenger(&self) -> Arc<SyncMessenger> is not possible to call mut methods?