use beteran_common_rust as bcr; use beteran_protobuf_rust as bpr; use prost::Message; /// pub struct Service { connection_broker: nats::asynk::Connection, queue_broker: String, } impl std::fmt::Debug for Service { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { f.debug_struct("beteran-frontend-server-edge::game::service::Service") .finish() } } impl Service { /// pub fn new(connection_broker: nats::asynk::Connection, queue_broker: String) -> Service { Service { connection_broker, queue_broker, } } pub async fn subscribe(&self) -> std::result::Result<(), std::boxed::Box> { futures::try_join!(self.list_games(),).map(|_| ()) } fn get_client_in_header( &self, message: &nats::asynk::Message, ) -> Result { match &message.headers { Some(headers) => { let client = match headers.get(bpr::c2se::core::network::HEADER_CLIENT) { Some(c) => { let msg = base64::decode(c).map_err(|e| { bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: format!("invalid header: {}", e), }) })?; bpr::models::core::network::Client::decode(msg.as_slice()).map_err(|e| { bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: format!("invalid header: {}", e), }) })? } None => { return Err(bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: "invalid client information".to_string(), })); } }; Ok(client) } None => Err(bcr::error::rpc::Error::Parse(bcr::error::rpc::Parse { message: "invalid header".to_string(), })), } } async fn list_games(&self) -> Result<(), Box> { let s = self .connection_broker .queue_subscribe( bpr::c2se::frontend::api::game::SUBJECT_LIST_GAMES, self.queue_broker.as_str(), ) .await?; while let Some(message) = s.next().await { if let Err(e) = async { let client = self.get_client_in_header(&message)?; let req = bpr::c2se::api::game::ListGamesRequest::decode(message.data.as_slice()).map_err(|e| { bcr::error::rpc::Error::InvalidRequest(bcr::error::rpc::InvalidRequest { message: format!("invalid request: {}", e), }) })?; let ss_list_games_req = bpr::ss::api::game::ListGamesRequest { client: Some(client), request: Some(bpr::ss::api::game::list_games_request::Request { pagination: req.pagination, sorts: req.sorts, search: match req.search { Some(s) => Some(bpr::ss::api::game::list_games_request::request::Search { vendor_id: s.vendor_id, key_like: s.key_like, category_like: s.category_like, platform_like: s.platform_like, game_type_like: s.game_type_like, }), None => None, }, }), }; let ss_list_games_res_msg = self .connection_broker .request( bpr::ss::api::game::SUBJECT_LIST_GAMES, ss_list_games_req.encode_to_vec(), ) .await .map_err(|e| { bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, }) })?; let ss_list_games_res = bpr::ss::api::game::ListGamesResponse::decode(ss_list_games_res_msg.data.as_slice()) .map_err(|e| { bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, }) })?; if let Some(e) = ss_list_games_res.error { return Err(bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, })); } if let Some(r) = ss_list_games_res.result { message .respond( bpr::c2se::api::game::ListGamesResponse { error: None, result: Some(bpr::c2se::api::game::list_games_response::Result { games: r.games }), } .encode_to_vec(), ) .await .map_err(|e| { bcr::error::rpc::Error::Server(bcr::error::rpc::Server { code: bpr::protobuf::rpc::Error::SERVER_00, message: format!("server {}", e), data: None, }) })?; } Ok::<(), bcr::error::rpc::Error>(()) } .await { message .respond( bpr::c2se::api::game::ListGamesResponse { error: Some(bpr::protobuf::rpc::Error::from(e)), result: None, } .encode_to_vec(), ) .await?; } } Ok(()) } }