(
&self,
path: &WorkspacePath,
content: &str,
expected_version: &str,
)
| 644 | } |
| 645 | |
| 646 | async fn write_text_if_version( |
| 647 | &self, |
| 648 | path: &WorkspacePath, |
| 649 | content: &str, |
| 650 | expected_version: &str, |
| 651 | ) -> WorkspaceResult<WorkspaceWriteOutcome> { |
| 652 | if expected_version.is_empty() { |
| 653 | return Err(WorkspaceError::InvalidArgument { |
| 654 | message: |
| 655 | "write_text_if_version requires a non-empty expected version (got empty); \ |
| 656 | use write_text for unconditional writes" |
| 657 | .to_string(), |
| 658 | }); |
| 659 | } |
| 660 | |
| 661 | let key = self.key_for(path); |
| 662 | let body = ByteStream::from(content.as_bytes().to_vec()); |
| 663 | let bytes = content.len() as u64; |
| 664 | |
| 665 | let start = std::time::Instant::now(); |
| 666 | let send_result = self |
| 667 | .client |
| 668 | .put_object() |
| 669 | .bucket(&self.bucket) |
| 670 | .key(&key) |
| 671 | .if_match(expected_version) |
| 672 | .body(body) |
| 673 | .content_type("text/plain; charset=utf-8") |
| 674 | .send() |
| 675 | .await; |
| 676 | emit_s3_call_event( |
| 677 | "s3.put_object_if_match", |
| 678 | &self.bucket, |
| 679 | &key, |
| 680 | bytes, |
| 681 | send_result.is_ok(), |
| 682 | start.elapsed(), |
| 683 | ); |
| 684 | |
| 685 | match send_result { |
| 686 | Ok(_) => Ok(WorkspaceWriteOutcome { |
| 687 | bytes: content.len(), |
| 688 | lines: content.lines().count(), |
| 689 | }), |
| 690 | Err(e) => Err(map_put_error(&self.bucket, &key, expected_version, e)), |
| 691 | } |
| 692 | } |
| 693 | } |
| 694 | |
| 695 | impl S3WorkspaceBackend { |
no test coverage detected