zoe_client/client/api/file_storage.rs
1use super::super::Client;
2use crate::ClientError;
3use crate::FileRef;
4use crate::error::Result;
5use std::path::PathBuf;
6use tokio::fs;
7
8#[cfg(feature = "frb-api")]
9use flutter_rust_bridge::frb;
10
11#[cfg_attr(feature = "frb-api", frb)]
12impl Client {
13 /// Store a file by reading from disk, encrypting, and storing in blob storage
14 ///
15 /// This method:
16 /// 1. Reads the file from the provided path
17 /// 2. Encrypts the content using convergent encryption
18 /// 3. Stores the encrypted data in the blob store
19 /// 4. Returns metadata needed to retrieve the file later
20 ///
21 /// # Arguments
22 ///
23 /// * `file_path` - Path to the file to store
24 ///
25 /// # Returns
26 ///
27 /// A `FileRef` containing the metadata needed to retrieve the file
28 ///
29 /// # Errors
30 ///
31 /// Returns an error if:
32 /// - The file cannot be read
33 /// - Encryption fails
34 /// - Blob storage operation fails
35 pub async fn store_file(&self, file_path: PathBuf) -> Result<FileRef> {
36 self.fs.store_file(&file_path).await
37 }
38
39 /// Store raw data (not from a file) with encryption and blob storage
40 ///
41 /// This method allows storing arbitrary data without reading from disk.
42 ///
43 /// # Arguments
44 ///
45 /// * `data` - The raw data to store
46 /// * `reference_name` - A reference name for the data (used in metadata)
47 /// * `content_type` - Optional content type for metadata
48 ///
49 /// # Returns
50 ///
51 /// `FileRef` containing the blob hash, encryption info, and metadata
52 pub async fn store_data(
53 &self,
54 data: &[u8],
55 reference_name: &str,
56 content_type: Option<String>,
57 ) -> Result<FileRef> {
58 self.fs.store_data(data, reference_name, content_type).await
59 }
60
61 /// Check if a file exists in storage
62 ///
63 /// # Arguments
64 ///
65 /// * `stored_info` - Metadata from when the file was stored
66 ///
67 /// # Returns
68 ///
69 /// `true` if the file exists in storage, `false` otherwise
70 pub async fn has_file(&self, stored_info: &FileRef) -> Result<bool> {
71 self.fs.has_file(stored_info).await
72 }
73
74 /// Retrieve a file from storage and save it to disk
75 ///
76 /// This method:
77 /// 1. Retrieves the encrypted data from blob storage using the FileRef
78 /// 2. Decrypts the content
79 /// 3. Writes the decrypted content to the specified path
80 ///
81 /// # Arguments
82 ///
83 /// * `file_ref` - Metadata for the file to retrieve
84 /// * `output_path` - Path where the decrypted file should be saved
85 ///
86 /// # Errors
87 ///
88 /// Returns an error if:
89 /// - The file cannot be found in storage
90 /// - Decryption fails
91 /// - Writing to disk fails
92 pub async fn retrieve_file(&self, file_ref: &FileRef, output_path: PathBuf) -> Result<()> {
93 // Get the file content from storage
94 let content = self.fs.retrieve_file(file_ref).await?;
95
96 // Write the content to the specified path
97 fs::write(&output_path, content)
98 .await
99 .map_err(ClientError::Io)?;
100
101 Ok(())
102 }
103
104 /// Retrieve a file from storage as bytes
105 ///
106 /// This method:
107 /// 1. Retrieves the encrypted data from blob storage using the FileRef
108 /// 2. Decrypts the content
109 /// 3. Returns the decrypted content as bytes
110 ///
111 /// # Arguments
112 ///
113 /// * `file_ref` - Metadata for the file to retrieve
114 ///
115 /// # Returns
116 ///
117 /// The decrypted file content as `Vec<u8>`
118 ///
119 /// # Errors
120 ///
121 /// Returns an error if:
122 /// - The file cannot be found in storage
123 /// - Decryption fails
124 pub async fn retrieve_file_bytes(&self, file_ref: &FileRef) -> Result<Vec<u8>> {
125 self.fs.retrieve_file(file_ref).await
126 }
127}