use crate::configuration::Commands; use super::grpc_juno; use grpc_juno::juno_services_server::{JunoServices, JunoServicesServer}; use grpc_juno::{EmptyRequest, EmptyResponse, GetFilesRequest, GetFilesResponse, PingResponse}; use std::error::Error; use std::net::SocketAddr; use std::path::PathBuf; use std::str::FromStr; use tokio::sync::mpsc::Sender; use tokio::sync::oneshot; use tonic::transport::Server; use tonic::{Request, Response, Result, Status}; type Responder = oneshot::Sender; pub enum GrpcServerMessage { Play { resp: Responder>, }, Pause { resp: Responder>, }, PlayPause { resp: Responder>, }, SkipSong { resp: Responder>, }, Set { resp: Responder>, }, GetFiles { path: PathBuf, resp: Responder>, }, } #[derive(Debug, Default)] pub struct GRPCServer { transmitter: Option>, } impl GRPCServer { pub fn new(tx: Sender) -> Self { Self { transmitter: Some(tx), } } pub async fn serve( address: SocketAddr, tx: Sender, ) -> Result<(), Box> { println!("Starting server on: \"{}\"", address.to_string()); Server::builder() .add_service(JunoServicesServer::new(GRPCServer::new(tx))) .serve(address) .await?; Ok(()) } } #[tonic::async_trait] impl JunoServices for GRPCServer { async fn ping( &self, _request: Request, ) -> Result, Status> { let reply = PingResponse { message: "pong!".to_string(), }; Ok(Response::new(reply)) } async fn get_files( &self, request: Request, ) -> Result, Status> { let path = PathBuf::from_str(request.into_inner().path.as_str()) .expect("Failed to create pathbuf"); let mut files: Vec = vec![]; if let Some(tx) = &self.transmitter { let (resp_tx, resp_rx) = oneshot::channel(); let message = GrpcServerMessage::GetFiles { resp: resp_tx, path, }; if let Err(_err) = tx.send(message).await { return Err(Status::internal("An internal error has occurred.")); } files = match resp_rx.await { Ok(response) => response, Err(_err) => return Err(Status::internal("An internal error has occurred.")), }; } let reply = GetFilesResponse { files: files.iter().map(|x| x.display().to_string()).collect(), }; Ok(Response::new(reply)) } async fn play( &self, _request: Request, ) -> Result, Status> { if let Some(tx) = &self.transmitter { let (resp_tx, resp_rx) = oneshot::channel(); let message = GrpcServerMessage::Play { resp: resp_tx }; if let Err(_err) = tx.send(message).await { return Err(Status::internal("An internal error has occurred.")); } if let Err(_err) = resp_rx.await { return Err(Status::internal("An internal error has occurred.")); } } Ok(Response::new(EmptyResponse {})) } async fn pause( &self, _request: Request, ) -> Result, Status> { if let Some(tx) = &self.transmitter { let (resp_tx, resp_rx) = oneshot::channel(); let message = GrpcServerMessage::Pause { resp: resp_tx }; if let Err(_err) = tx.send(message).await { return Err(Status::internal("An internal error has occurred.")); } if let Err(_err) = resp_rx.await { return Err(Status::internal("An internal error has occurred.")); } } Ok(Response::new(EmptyResponse {})) } async fn play_pause( &self, _request: Request, ) -> Result, Status> { if let Some(tx) = &self.transmitter { let (resp_tx, resp_rx) = oneshot::channel(); let message = GrpcServerMessage::PlayPause { resp: resp_tx }; if let Err(_err) = tx.send(message).await { return Err(Status::internal("An internal error has occurred.")); } if let Err(_err) = resp_rx.await { return Err(Status::internal("An internal error has occurred.")); } } Ok(Response::new(EmptyResponse {})) } async fn skip_song( &self, _request: Request, ) -> Result, Status> { if let Some(tx) = &self.transmitter { let (resp_tx, resp_rx) = oneshot::channel(); let message = GrpcServerMessage::SkipSong { resp: resp_tx }; if let Err(_err) = tx.send(message).await { return Err(Status::internal("An internal error has occurred.")); } if let Err(_err) = resp_rx.await { return Err(Status::internal("An internal error has occurred.")); } } Ok(Response::new(EmptyResponse {})) } }