7WM64CI7MA25GOY5BEQQQFUXNKLXSAN65VX7XA3UGJKGS6OVLUAQC NXDEBFWRTMIXUI4G4QV67Z3C2AH7YL777F3V42XMEP3Q6LC63SOAC KORYGY74MKXQZSV6JOJJCHPG3CC5UM2LTNIEV5UAJGZS7QCDKDLQC CCLGGFKRUNXBM6IOGEYJOFULCSVOL6C5PFAGCKEWNXOZIKPWLLWQC LL3D5CXKPWIGTQ7MFK4YXDGDZOKD6CU5WCIWV3FG6TPGQOGD75QAC FVVPKFTLD5VOGVDF7MOSSKQ3KPCT4HDGTNTTC6I6B4TWXOTPCJ7AC JY4F7VBCS4S2YYXT7JQBLPSCWW3K4H3NXH6G5WGJFWWQXN2YPIQAC fn process_jid(&mut self, xmpp_to: &xmpp_parsers::Jid) {if let Some(ref mut mailbox) = self.state.data.outgoing_mailbox.get_mut(xmpp_to) {if !mailbox.is_empty() {if let Some(ref mut rdata) = self.state.data.roster.get_mut(&std::convert::From::from(xmpp_to.clone())){info!("Jid {} in roster", xmpp_to);let sub_to = match rdata.0 {xmpp_parsers::roster::Subscription::To => true,xmpp_parsers::roster::Subscription::Both => true,_ => false,};if sub_to {info!("Subscribed to {}", xmpp_to);self.state.data.send_queue.extend(mailbox.drain(..).map(|message| {stanzas::make_chat_message(xmpp_to.clone(), message)}),);} else if rdata.1 == xmpp_parsers::roster::Ask::None {info!("Not subscribed to {}", xmpp_to);self.state.data.counter += 1;let id_presence_subscribe =format!("id_presence_subscribe{}", self.state.data.counter);self.state.data.send_queue.push_back(stanzas::make_ask_subscribe(id_presence_subscribe,xmpp_to.clone(),));} else {warn!("Not subscribed to {}. Currently in {:?} state",xmpp_to, rdata.1);self.state.data.counter += 1;let id_presence_subscribe =format!("id_presence_subscribe{}", self.state.data.counter);self.state.data.send_queue.push_back(stanzas::make_ask_subscribe(id_presence_subscribe,xmpp_to.clone(),));}let sub_from = match rdata.0 {xmpp_parsers::roster::Subscription::From => true,xmpp_parsers::roster::Subscription::Both => true,_ => false,};if !sub_from {info!("Not subscription from {}", xmpp_to);self.state.data.counter += 1;let id_presence_subscribed =format!("id_presence_subscribed{}", self.state.data.counter);self.state.data.send_queue.push_back(stanzas::make_allow_subscribe(id_presence_subscribed,xmpp_to.clone(),));}} else {info!("Jid {} not in roster", xmpp_to);self.state.data.counter += 1;let id_add_roster = format!("id_add_roster{}", self.state.data.counter);let add_roster = stanzas::make_add_roster(&id_add_roster,std::convert::From::from(xmpp_to.clone()),);info!("Adding jid {} to roster id {}", xmpp_to, id_add_roster);self.state.data.pending_ids.insert(id_add_roster,IqWait::new(60,AddRosterIqHandler {jid: std::convert::From::from(xmpp_to.clone()),},),);self.state.data.send_queue.push_back(add_roster);}}}}
XmppCommand::Chat { xmpp_to, message } => {self.state.data.outgoing_mailbox.entry(xmpp_to.clone()).or_default().push(message);self.process_jid(&xmpp_to);}XmppCommand::Chatroom { muc_id, message } => {if let Some(muc) = self.state.data.mucs.get(&muc_id) {self.state.data.send_queue.push_back(stanzas::make_muc_message(muc.clone(), message));} else {error!("Not found MUC {}", muc_id);}}XmppCommand::ChatroomPresence {muc_id,show,message,} => {if let Some(muc) = self.state.data.mucs.get(&muc_id) {self.state.data.counter += 1;let id_presence = format!("id_presence{}", self.state.data.counter);self.state.data.send_queue.push_back(stanzas::make_muc_presence(&id_presence,self.account.jid.clone(),muc.clone(),Some(show),Some(message),));} else {error!("Not found MUC {}", muc_id);}}
type Func<S, T, E> = dyn Fn(&mut S, E) -> T + Sync;pub struct Processor<S: 'static, T: 'static, E: Clone + 'static> {processors: Vec<Box<Func<S, Option<T>, E>>>,default: &'static Func<S, T, E>,}impl<S: 'static, T: 'static, E: Clone + 'static> Processor<S, T, E> {pub fn new<F>(f: &'static F) -> Processor<S, T, E>whereF: Fn(&mut S, E) -> T + Sync + 'static,{Processor {processors: vec![],default: f,}}pub fn register<F, A>(&mut self, f: &'static F)whereF: Fn(&mut S, A) -> T + Sync + 'static,A: std::convert::TryFrom<E>,{self.processors.push(Box::new(move |s, e: E| {use std::convert::TryInto;(e.try_into().ok() as Option<A>).map(|a| f(s, a))}));}pub fn process(&self, s: &mut S, e: E) -> T {for processor in self.processors.iter() {match processor(s, e.clone()) {Some(t) => return t,None => continue,}}(*self.default)(s, e)}}
type Func<S, T, E> = dyn Fn(&mut S, E) -> T + Sync;pub struct Processor<S: 'static, T: 'static, E: Clone + 'static> {processors: Vec<Box<Func<S, Option<T>, E>>>,default: &'static Func<S, T, E>,}impl<S: 'static, T: 'static, E: Clone + 'static> Processor<S, T, E> {pub fn new<F>(f: &'static F) -> Processor<S, T, E>whereF: Fn(&mut S, E) -> T + Sync + 'static,{Processor {processors: vec![],default: f,}}pub fn register<F, A>(&mut self, f: &'static F)whereF: Fn(&mut S, A) -> T + Sync + 'static,A: std::convert::TryFrom<E>,{self.processors.push(Box::new(move |s, e: E| {use std::convert::TryInto;(e.try_into().ok() as Option<A>).map(|a| f(s, a))}));}pub fn process(&self, s: &mut S, e: E) -> T {for processor in self.processors.iter() {match processor(s, e.clone()) {Some(t) => return t,None => continue,}}(*self.default)(s, e)}}
.body(Body::from(format!("Cann't get presence text")))
.body(Body::from(format!("Cann't send command"))).map_err(std::convert::Into::into)}}}Err(e) => Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't get presence text"))).map_err(std::convert::Into::into),}})}(None, Ok(xmpp_to), _) => {info!("Got chat request. Reading body...");let mut cmd_send = self.cmd_send.clone();Box::pin(async move {match body_to_string(req).await {Ok(message) => {match cmd_send.send(XmppCommand::Chat { xmpp_to, message }).await {Ok(_) => Response::builder().body(Body::from(format!("Accepted"))).map_err(std::convert::Into::into),Err(e) => {error!("Cann't send chat command: {}", e);Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't send command"))).map_err(std::convert::Into::into)}}}Err(e) => Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't get chat text"))).map_err(std::convert::Into::into),}})}(Some(Ok(muc_id)), _, Ok(show)) => {info!("Got MUC presence request. Reading body...");let mut cmd_send = self.cmd_send.clone();Box::pin(async move {match body_to_string(req).await {Ok(message) => {match cmd_send.send(XmppCommand::ChatroomPresence {muc_id,show,message,}).await{Ok(_) => Response::builder().body(Body::from(format!("Accepted"))).map_err(std::convert::Into::into),Err(e) => {error!("Cann't send MUC presence command: {}", e);Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't send command")))
(None, Ok(xmpp_to), _) => Box::pin(async {Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("SOON"))).map_err(std::convert::Into::into)}),(Some(Ok(muc_id)), _, Ok(show)) => Box::pin(async {Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("SOON"))).map_err(std::convert::Into::into)}),(Some(Ok(muc_id)), _, _) => Box::pin(async {Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("SOON"))).map_err(std::convert::Into::into)}),(Some(Err(err)), _, _) => Box::pin(async {Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("SOON"))).map_err(std::convert::Into::into)}),
(Some(Ok(muc_id)), _, _) => {info!("Got MUC chat request. Reading body...");let mut cmd_send = self.cmd_send.clone();Box::pin(async move {match body_to_string(req).await {Ok(message) => {match cmd_send.send(XmppCommand::Chatroom { muc_id, message }).await{Ok(_) => Response::builder().body(Body::from(format!("Accepted"))).map_err(std::convert::Into::into),Err(e) => {error!("Cann't send MUC chat command: {}", e);Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't send command"))).map_err(std::convert::Into::into)}}}Err(e) => Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Cann't get chat text"))).map_err(std::convert::Into::into),}})}(Some(Err(err)), _, _) => {warn!("Unknown muc destination: {}", err);Box::pin(async move {Response::builder().status(hyper::StatusCode::BAD_REQUEST).body(Body::from(format!("Unknown muc destination: {}", err,))).map_err(std::convert::Into::into)})}