You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
4.3 KiB
115 lines
4.3 KiB
//! Shared behaviour for contact factories/stores. |
|
|
|
use huawei_modem::pdu::PduAddress; |
|
use crate::models::{Recipient, Message}; |
|
use crate::store::Store; |
|
use crate::comm::ContactManagerCommand; |
|
use crate::util::Result; |
|
use futures::sync::mpsc::UnboundedSender; |
|
use crate::comm::{WhatsappCommand, ModemCommand, ControlBotCommand}; |
|
|
|
pub trait ContactManagerManager { |
|
fn wa_tx(&mut self) -> &mut UnboundedSender<WhatsappCommand>; |
|
fn m_tx(&mut self) -> &mut UnboundedSender<ModemCommand>; |
|
fn cb_tx(&mut self) -> &mut UnboundedSender<ControlBotCommand>; |
|
fn setup_contact_for(&mut self, _: Recipient, _: PduAddress) -> Result<()>; |
|
fn remove_contact_for(&mut self, _: &PduAddress) -> Result<()>; |
|
fn has_contact(&mut self, _: &PduAddress) -> bool; |
|
fn store(&mut self) -> &mut Store; |
|
fn forward_cmd(&mut self, _: &PduAddress, _: ContactManagerCommand) -> Result<()>; |
|
fn resolve_nick(&self, _: &str) -> Option<PduAddress>; |
|
fn setup_recipient(&mut self, recip: Recipient) -> Result<()> { |
|
let addr = recip.get_addr()?; |
|
debug!("Setting up recipient for {} (nick {})", addr, recip.nick); |
|
if self.has_contact(&addr) { |
|
debug!("Not doing anything; contact already exists"); |
|
return Ok(()); |
|
} |
|
self.setup_contact_for(recip, addr)?; |
|
Ok(()) |
|
} |
|
fn query_contact(&mut self, a: PduAddress, src: i32) -> Result<()> { |
|
if let Some(recip) = self.store().get_recipient_by_addr_opt(&a)? { |
|
self.cb_tx().unbounded_send( |
|
ControlBotCommand::CommandResponse( |
|
format!("Ghost exists already; nickname is `{}`.", recip.nick) |
|
)) |
|
.unwrap(); |
|
self.setup_recipient(recip)?; |
|
} |
|
else { |
|
self.cb_tx().unbounded_send( |
|
ControlBotCommand::CommandResponse( |
|
format!("Setting up a ghost for number `{}`...", a) |
|
)) |
|
.unwrap(); |
|
self.request_contact(a, src)?; |
|
} |
|
Ok(()) |
|
} |
|
fn setup_contact(&mut self, a: PduAddress) -> Result<()> { |
|
if let Some(recip) = self.store().get_recipient_by_addr_opt(&a)? { |
|
self.setup_recipient(recip)?; |
|
} |
|
else { |
|
error!("Attempted to setup non-existent recipient {}", a); |
|
} |
|
Ok(()) |
|
} |
|
fn request_contact(&mut self, a: PduAddress, src: i32) -> Result<bool> { |
|
if let Some(recip) = self.store().get_recipient_by_addr_opt(&a)? { |
|
self.setup_recipient(recip)?; |
|
Ok(true) |
|
} |
|
else { |
|
info!("No contact exists yet for {}; asking for its creation", a); |
|
match src { |
|
Message::SOURCE_SMS => { |
|
self.m_tx().unbounded_send(ModemCommand::MakeContact(a)) |
|
.unwrap(); |
|
}, |
|
Message::SOURCE_WA => { |
|
self.wa_tx().unbounded_send(WhatsappCommand::MakeContact(a)) |
|
.unwrap(); |
|
}, |
|
_ => { |
|
error!("Contact requested for unknown message source {}", src); |
|
} |
|
} |
|
Ok(false) |
|
} |
|
} |
|
fn drop_contact(&mut self, addr: PduAddress) -> Result<()> { |
|
info!("Dropping contact {}", addr); |
|
self.store().delete_recipient_with_addr(&addr)?; |
|
self.remove_contact_for(&addr)?; |
|
Ok(()) |
|
} |
|
fn subscribe_presence_by_nick(&mut self, nick: String) { |
|
if let Some(a) = self.resolve_nick(&nick) { |
|
self.wa_tx().unbounded_send(WhatsappCommand::SubscribePresence(a)) |
|
.unwrap(); |
|
} |
|
else { |
|
warn!("Tried to subscribe presence for nonexistent nick {}", nick); |
|
} |
|
} |
|
fn drop_contact_by_nick(&mut self, nick: String) -> Result<()> { |
|
if let Some(a) = self.resolve_nick(&nick) { |
|
self.drop_contact(a)?; |
|
} |
|
else { |
|
warn!("Tried to drop nonexistent contact with nick {}", nick); |
|
} |
|
Ok(()) |
|
} |
|
fn forward_cmd_by_nick(&mut self, nick: &str, cmd: ContactManagerCommand) -> Result<()> { |
|
if let Some(a) = self.resolve_nick(nick) { |
|
self.forward_cmd(&a, cmd)?; |
|
} |
|
else { |
|
warn!("Could not resolve forwarded command intended for {}", nick); |
|
} |
|
Ok(()) |
|
} |
|
}
|
|
|