google_cloud_bigquery/write/
append_response.rs1use super::error::{AppendError, AppendResult};
16use crate::Error;
17use crate::model::append_rows_response::Response;
18use crate::model::{AppendRowsResponse, TableSchema};
19
20#[derive(Clone, Debug, Default, PartialEq)]
22#[non_exhaustive]
23pub struct AppendResponse {
24 pub offset: Option<i64>,
27
28 pub updated_schema: Option<TableSchema>,
37}
38
39pub(crate) fn to_result(resp: AppendRowsResponse) -> AppendResult<AppendResponse> {
40 if !resp.row_errors.is_empty() {
41 return Err(AppendError::RowErrors(resp.row_errors));
42 }
43
44 let offset = match resp.response {
45 None => None,
46 Some(Response::AppendResult(r)) => r.offset,
47 Some(Response::Error(s)) => {
48 return Err(Error::service((*s).into()).into());
49 }
50 };
51 Ok(AppendResponse {
52 offset,
53 updated_schema: resp.updated_schema,
54 })
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::model::RowError;
61 use crate::model::append_rows_response::AppendResult;
62 use crate::model::row_error::RowErrorCode;
63 use google_cloud_gax::error::rpc::Code;
64 use google_cloud_rpc::model::Status as RpcStatus;
65
66 fn schema() -> TableSchema {
67 TableSchema::new()
68 }
69
70 fn row_error(index: i64) -> RowError {
71 RowError::new()
72 .set_index(index)
73 .set_code(RowErrorCode::FieldsError)
74 .set_message("fail")
75 }
76
77 #[test]
78 fn success() -> anyhow::Result<()> {
79 let resp = AppendRowsResponse::new()
80 .set_append_result(AppendResult::new().set_offset(42))
81 .set_updated_schema(schema());
82
83 let res = to_result(resp)?;
84 assert_eq!(res.offset, Some(42));
85 assert_eq!(res.updated_schema, Some(schema()));
86 Ok(())
87 }
88
89 #[test]
90 fn rpc_error() {
91 let resp = AppendRowsResponse::new().set_error(
92 RpcStatus::new()
93 .set_code(Code::InvalidArgument as i32)
94 .set_message("fail"),
95 );
96
97 let err = to_result(resp).expect_err("should error");
98 let AppendError::Rpc { source } = err else {
99 panic!("Expected AppendError::Rpc, got {:?}", err);
100 };
101 let status = source.status().expect("status should be set");
102 assert_eq!(status.code, Code::InvalidArgument);
103 assert_eq!(status.message, "fail");
104 }
105
106 #[test]
107 fn row_errors() {
108 let resp = AppendRowsResponse::new().set_row_errors(vec![row_error(1), row_error(2)]);
109
110 let err = to_result(resp).expect_err("should error");
111 let AppendError::RowErrors(errors) = err else {
112 panic!("Expected AppendError::RowErrors, got {:?}", err);
113 };
114 assert_eq!(errors, vec![row_error(1), row_error(2)]);
115 }
116
117 #[test]
118 fn unset_response() -> anyhow::Result<()> {
119 let resp = AppendRowsResponse::new().set_updated_schema(schema());
120 let res = to_result(resp)?;
121 assert_eq!(res.offset, None);
122 assert_eq!(res.updated_schema, Some(schema()));
123 Ok(())
124 }
125}