use crate::google;
use gaxi::prost::{ConvertError, FromProto, ToProto};
use crate::generated::gapic_control::transport::{lro_any_from_prost, lro_any_to_prost};
impl ToProto<google::longrunning::Operation> for google_cloud_longrunning::model::Operation {
type Output = google::longrunning::Operation;
fn to_proto(
self,
) -> std::result::Result<google::longrunning::Operation, gaxi::prost::ConvertError> {
use google::longrunning::operation::Result as P;
use google_cloud_longrunning::model::operation::Result as M;
let metadata = self.metadata.map(lro_any_to_prost).transpose()?;
#[warn(clippy::wildcard_enum_match_arm)]
let result = self
.result
.map(|result| match result {
M::Error(status) => status.to_proto().map(P::Error),
M::Response(any) => lro_any_to_prost(*any).map(P::Response),
_ => unreachable!(),
})
.transpose()?;
Ok(google::longrunning::Operation {
name: self.name,
metadata,
done: self.done,
result,
})
}
}
impl FromProto<google_cloud_longrunning::model::Operation> for google::longrunning::Operation {
fn cnv(self) -> std::result::Result<google_cloud_longrunning::model::Operation, ConvertError> {
use google::longrunning::operation::Result as P;
use google_cloud_longrunning::model::operation::Result as M;
let metadata = self.metadata.map(lro_any_from_prost).transpose()?;
let result = self
.result
.map(|result| match result {
P::Error(status) => status.cnv().map(|s| M::Error(s.into())),
P::Response(any) => lro_any_from_prost(any).map(|r| M::Response(r.into())),
})
.transpose()?;
Ok(google_cloud_longrunning::model::Operation::new()
.set_name(self.name)
.set_or_clear_metadata(metadata)
.set_done(self.done)
.set_result(result))
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_case::test_case;
fn prost_folder() -> prost_types::Any {
let folder = google::storage::control::v2::Folder {
name: "test-name".to_string(),
metageneration: 42,
..Default::default()
};
prost_types::Any::from_msg(&folder).unwrap()
}
fn wkt_folder() -> wkt::Any {
let folder = crate::model::Folder::new()
.set_name("test-name")
.set_metageneration(42);
wkt::Any::from_msg(&folder).unwrap()
}
fn prost_create_metadata() -> prost_types::Any {
let md = google::storage::control::v2::CreateAnywhereCacheMetadata {
zone: Some("test-zone".to_string()),
..Default::default()
};
prost_types::Any::from_msg(&md).unwrap()
}
fn wkt_create_metadata() -> wkt::Any {
let md = crate::model::CreateAnywhereCacheMetadata::new().set_zone("test-zone".to_string());
wkt::Any::from_msg(&md).unwrap()
}
fn prost_empty() -> prost_types::Any {
let empty = gaxi::prost::Empty {};
prost_types::Any::from_msg(&empty).unwrap()
}
fn wkt_empty() -> wkt::Any {
let empty = wkt::Empty {};
wkt::Any::from_msg(&empty).unwrap()
}
fn wkt_lro_with_metadata() -> google_cloud_longrunning::model::Operation {
google_cloud_longrunning::model::Operation::new()
.set_name("name")
.set_metadata(wkt_create_metadata())
}
fn prost_lro_with_metadata() -> google::longrunning::Operation {
google::longrunning::Operation {
name: "name".to_string(),
metadata: Some(prost_create_metadata()),
..Default::default()
}
}
fn wkt_lro_with_response() -> google_cloud_longrunning::model::Operation {
google_cloud_longrunning::model::Operation::new()
.set_name("name")
.set_done(true)
.set_response(wkt_folder())
}
fn prost_lro_with_response() -> google::longrunning::Operation {
google::longrunning::Operation {
name: "name".to_string(),
done: true,
result: Some(google::longrunning::operation::Result::Response(
prost_folder(),
)),
..Default::default()
}
}
fn wkt_lro_with_error() -> google_cloud_longrunning::model::Operation {
google_cloud_longrunning::model::Operation::new()
.set_name("name")
.set_done(true)
.set_error(google_cloud_rpc::model::Status::new().set_code(5))
}
fn prost_lro_with_error() -> google::longrunning::Operation {
google::longrunning::Operation {
name: "name".to_string(),
done: true,
result: Some(google::longrunning::operation::Result::Error(
google::rpc::Status {
code: 5,
..Default::default()
},
)),
..Default::default()
}
}
#[test_case(Default::default(), Default::default(); "empty LROs")]
#[test_case(prost_lro_with_metadata(), wkt_lro_with_metadata(); "with metadata")]
#[test_case(prost_lro_with_response(), wkt_lro_with_response(); "with response")]
#[test_case(prost_lro_with_error(), wkt_lro_with_error(); "with error")]
fn lro_roundtrip(
prost: google::longrunning::Operation,
wkt: google_cloud_longrunning::model::Operation,
) -> anyhow::Result<()> {
assert_eq!(prost, wkt.clone().to_proto()?);
assert_eq!(wkt, prost.cnv()?);
Ok(())
}
#[test]
fn lro_to_prost_unknown_metadata() -> anyhow::Result<()> {
let wkt = google_cloud_longrunning::model::Operation::new()
.set_metadata(wkt::Any::from_msg(&wkt::Duration::default())?);
let prost = wkt.to_proto();
assert!(matches!(prost, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
#[test]
fn lro_to_prost_unknown_response() -> anyhow::Result<()> {
let wkt = google_cloud_longrunning::model::Operation::new()
.set_response(wkt::Any::from_msg(&wkt::Duration::default())?);
let prost = wkt.to_proto();
assert!(matches!(prost, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
#[test]
fn lro_from_prost_unknown_metadata() -> anyhow::Result<()> {
let unknown = prost_types::Any::from_msg(&prost_types::Duration::default())?;
let prost = google::longrunning::Operation {
metadata: Some(unknown),
..Default::default()
};
let wkt = prost.cnv();
assert!(matches!(wkt, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
#[test]
fn lro_from_prost_unknown_response() -> anyhow::Result<()> {
let unknown = prost_types::Any::from_msg(&prost_types::Duration::default())?;
let prost = google::longrunning::Operation {
result: Some(google::longrunning::operation::Result::Response(unknown)),
..Default::default()
};
let wkt = prost.cnv();
assert!(matches!(wkt, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
#[test_case(prost_types::Any::default(), wkt::Any::default(); "default Any")]
#[test_case(prost_folder(), wkt_folder(); "Any with LRO response type")]
#[test_case(prost_create_metadata(), wkt_create_metadata(); "Any with LRO metadata type")]
#[test_case(prost_empty(), wkt_empty(); "Any with Empty")]
fn lro_any_roundtrip(prost: prost_types::Any, wkt: wkt::Any) -> anyhow::Result<()> {
assert_eq!(prost, lro_any_to_prost(wkt.clone())?);
assert_eq!(wkt, lro_any_from_prost(prost)?);
Ok(())
}
#[test]
fn lro_any_to_prost_unknown_type() -> anyhow::Result<()> {
let wkt = wkt::Any::from_msg(&wkt::Duration::default())?;
let prost = lro_any_to_prost(wkt);
assert!(matches!(prost, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
#[test]
fn lro_any_from_prost_unknown_type() -> anyhow::Result<()> {
let unknown = prost_types::Duration::default();
let prost = prost_types::Any::from_msg(&unknown)?;
let wkt = lro_any_from_prost(prost);
assert!(matches!(wkt, Err(ConvertError::UnexpectedTypeUrl(_))));
Ok(())
}
}