use std::sync::Arc; use tonic::{Request, Response, Status}; use crate::rpc::{ error::{spawn_blocking_error, to_status}, proto as p, registry::RepoRegistry, }; pub struct MergeServiceImpl { pub registry: Arc, } #[tonic::async_trait] impl p::merge_service_server::MergeService for MergeServiceImpl { async fn merge_base( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let a: crate::cmd::oid::ObjectId = inner.oid_a.unwrap_or_default().into(); let b: crate::cmd::oid::ObjectId = inner.oid_b.unwrap_or_default().into(); let result = tokio::task::spawn_blocking(move || bare.merge_base(a, b)) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeBaseResponse { base_oid: Some(result.into()), })) } async fn merge_base_many( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let oids = inner.oids.into_iter().map(Into::into).collect::>(); let result = tokio::task::spawn_blocking(move || bare.merge_base_many(oids)) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeBaseManyResponse { base_oid: Some(result.into()), })) } async fn merge_base_octopus( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let oids = inner.oids.into_iter().map(Into::into).collect::>(); let result = tokio::task::spawn_blocking(move || bare.merge_base_octopus(oids)) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeBaseOctopusResponse { base_oid: Some(result.into()), })) } async fn merge_analysis( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let their_commit: crate::cmd::oid::ObjectId = inner.oid_a.unwrap_or_default().into(); let result = tokio::task::spawn_blocking(move || { bare.merge_analysis(their_commit) }) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeAnalysisResponse { analysis: Some(result.0.into()), preference: Some(result.1.into()), })) } async fn merge_analysis_for_ref( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let ref_name = inner.ref_name.clone(); let result = tokio::task::spawn_blocking(move || { bare.merge_analysis_for_ref(ref_name) }) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeAnalysisForRefResponse { analysis: Some(result.0.into()), preference: Some(result.1.into()), })) } async fn merge_is_conflicted( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let result = tokio::task::spawn_blocking(move || bare.merge_is_conflicted()) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeIsConflictedResponse { is_conflicted: result, })) } async fn mergehead_list( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let result = tokio::task::spawn_blocking(move || bare.mergehead_list()) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeheadListResponse { oids: result.into_iter().map(Into::into).collect(), })) } async fn merge_tree( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let ours: crate::cmd::oid::ObjectId = inner.ours.unwrap_or_default().into(); let theirs: crate::cmd::oid::ObjectId = inner.theirs.unwrap_or_default().into(); let options = inner.options.map(Into::into); let result = tokio::task::spawn_blocking(move || { bare.merge_tree(ours, theirs, options) }) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeTreeResponse { result: Some(result.into()), })) } async fn merge_commit( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let params = inner.params.unwrap_or_default().into(); let result = tokio::task::spawn_blocking(move || bare.merge_commit(params)) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeCommitResponse { oid: Some(result.into()), })) } async fn squash_commit( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let params = inner.params.unwrap_or_default().into(); let result = tokio::task::spawn_blocking(move || bare.squash_commit(params)) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::SquashCommitResponse { oid: Some(result.into()), })) } async fn merge_abort( &self, req: Request, ) -> Result, Status> { let inner = req.into_inner(); let bare = self.registry.get(&inner.repo_id).await?; let _result = tokio::task::spawn_blocking(move || bare.merge_abort()) .await .map_err(spawn_blocking_error)? .map_err(to_status)?; Ok(Response::new(p::MergeAbortResponse {})) } }