@anysphere/file-service 0.0.0-a74cc2fc → 0.0.0-a75b800f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -3,18 +3,89 @@
3
3
 
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
- export class MerkleClient {
6
+ export declare function hashBytes(bytes: Uint8Array): string
7
+ export const enum DiffType {
8
+ Insert = 'Insert',
9
+ Delete = 'Delete',
10
+ Equal = 'Equal'
11
+ }
12
+ export interface DiffChunk {
13
+ diffType: DiffType
14
+ text: string
15
+ }
16
+ export interface WalkDirConfig {
17
+ maxNumFiles: number
18
+ }
19
+ export interface CommitData {
20
+ sha: string
21
+ date: number
22
+ message: string
23
+ author: string
24
+ parents: Array<string>
25
+ files: Array<CommitFile>
26
+ }
27
+ export interface CommitFile {
28
+ from: string
29
+ to: string
30
+ additions: number
31
+ deletions: number
32
+ status: CommitFileStatus
33
+ }
34
+ export const enum CommitFileStatus {
35
+ Added = 0,
36
+ Deleted = 1,
37
+ Modified = 2,
38
+ Renamed = 3
39
+ }
40
+ export const enum CommitChainGetFiles {
41
+ DoGetFiles = 0,
42
+ DontGetFiles = 1
43
+ }
44
+ export interface VerifyData {
45
+ commitTime: number
46
+ fileContent: string
47
+ filePath: string
48
+ }
49
+ export interface Candidate {
50
+ path: string
51
+ locations: Array<number>
52
+ weight: number
53
+ }
54
+ export declare class DiffClient {
55
+ constructor()
56
+ diff(text1: string, text2: string): Array<DiffChunk>
57
+ /**
58
+ * use https://docs.rs/diffmatchpatch/latest/diffmatchpatch/struct.DiffMatchPatch.html#method.diff_lines_to_chars
59
+ * then diff the chars.
60
+ * then convert back to lines.
61
+ *
62
+ * takes in two strings. splits based on newlines.
63
+ * returns diffs based on lines.
64
+ */
65
+ diffLines(text1: string, text2: string): Array<DiffChunk>
66
+ }
67
+ export declare class MerkleClient {
7
68
  constructor(absoluteRootDirectory: string)
8
- init(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
9
- computeMerkleTree(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
10
- updateFile(filePath: string): Promise<void>
11
- deleteFile(filePath: string): Promise<void>
69
+ initWithRipgrepIgnore(logFilesPath: string | undefined | null, config: WalkDirConfig): Promise<void>
12
70
  getSubtreeHash(relativePath: string): Promise<string>
13
71
  getNumEmbeddableFiles(): Promise<number>
72
+ getImportantPaths(k: number): Promise<Array<string>>
14
73
  getAllFiles(): Promise<Array<string>>
15
74
  getAllDirFilesToEmbed(absoluteFilePath: string): Promise<Array<string>>
16
- getNextFileToEmbed(): Promise<Array<string>>
17
- getSpline(absoluteFilePath: string): Promise<Array<string>>
18
- getHashesForFiles(files: Array<string>): Promise<Array<string>>
19
- updateRootDirectory(rootDirectory: string): void
75
+ }
76
+ export declare class GitClient {
77
+ constructor(absoluteRootDirectory: string)
78
+ getTotalCommitCount(): Promise<number>
79
+ getCommitVerifyData(commit: string): Promise<VerifyData>
80
+ throwIfCommitDoesntExist(rootSha: string): Promise<void>
81
+ getVerifyCommit(): Promise<string>
82
+ getRepoHeadSha(): Promise<string | null>
83
+ getCommitChain(hash: string, depth: number, getFiles: CommitChainGetFiles): Promise<Array<CommitData>>
84
+ }
85
+ export declare class GitFile {
86
+ findSimilarFiles(lineno: number): Promise<Array<Candidate>>
87
+ }
88
+ export declare class LocalGitGraph {
89
+ constructor(repo: string)
90
+ openFile(path: string): Promise<GitFile>
20
91
  }
package/index.js CHANGED
@@ -224,14 +224,72 @@ switch (platform) {
224
224
  }
225
225
  break
226
226
  case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'file_service.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./file_service.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@anysphere/file-service-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'file_service.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./file_service.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@anysphere/file-service-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'file_service.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./file_service.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@anysphere/file-service-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'file_service.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./file_service.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@anysphere/file-service-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
227
285
  localFileExisted = existsSync(
228
- join(__dirname, 'file_service.linux-arm-gnueabihf.node')
286
+ join(__dirname, 'file_service.linux-s390x-gnu.node')
229
287
  )
230
288
  try {
231
289
  if (localFileExisted) {
232
- nativeBinding = require('./file_service.linux-arm-gnueabihf.node')
290
+ nativeBinding = require('./file_service.linux-s390x-gnu.node')
233
291
  } else {
234
- nativeBinding = require('@anysphere/file-service-linux-arm-gnueabihf')
292
+ nativeBinding = require('@anysphere/file-service-linux-s390x-gnu')
235
293
  }
236
294
  } catch (e) {
237
295
  loadError = e
@@ -252,6 +310,14 @@ if (!nativeBinding) {
252
310
  throw new Error(`Failed to load native binding`)
253
311
  }
254
312
 
255
- const { MerkleClient } = nativeBinding
313
+ const { hashBytes, DiffType, DiffClient, MerkleClient, GitClient, CommitFileStatus, CommitChainGetFiles, GitFile, LocalGitGraph } = nativeBinding
256
314
 
315
+ module.exports.hashBytes = hashBytes
316
+ module.exports.DiffType = DiffType
317
+ module.exports.DiffClient = DiffClient
257
318
  module.exports.MerkleClient = MerkleClient
319
+ module.exports.GitClient = GitClient
320
+ module.exports.CommitFileStatus = CommitFileStatus
321
+ module.exports.CommitChainGetFiles = CommitChainGetFiles
322
+ module.exports.GitFile = GitFile
323
+ module.exports.LocalGitGraph = LocalGitGraph
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anysphere/file-service",
3
- "version": "0.0.0-a74cc2fc",
3
+ "version": "0.0.0-a75b800f",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "napi": {
@@ -14,9 +14,13 @@
14
14
  ]
15
15
  }
16
16
  },
17
+ "files": [
18
+ "index.js",
19
+ "index.d.ts"
20
+ ],
17
21
  "license": "MIT",
18
22
  "devDependencies": {
19
- "@napi-rs/cli": "^2.16.2",
23
+ "@napi-rs/cli": "^2.18.4",
20
24
  "ava": "^5.1.1"
21
25
  },
22
26
  "ava": {
@@ -36,12 +40,12 @@
36
40
  "version": "napi version"
37
41
  },
38
42
  "optionalDependencies": {
39
- "@anysphere/file-service-win32-x64-msvc": "0.0.0-a74cc2fc",
40
- "@anysphere/file-service-darwin-x64": "0.0.0-a74cc2fc",
41
- "@anysphere/file-service-linux-x64-gnu": "0.0.0-a74cc2fc",
42
- "@anysphere/file-service-darwin-arm64": "0.0.0-a74cc2fc",
43
- "@anysphere/file-service-win32-arm64-msvc": "0.0.0-a74cc2fc",
44
- "@anysphere/file-service-darwin-universal": "0.0.0-a74cc2fc",
45
- "@anysphere/file-service-linux-arm64-gnu": "0.0.0-a74cc2fc"
43
+ "@anysphere/file-service-win32-x64-msvc": "0.0.0-a75b800f",
44
+ "@anysphere/file-service-darwin-x64": "0.0.0-a75b800f",
45
+ "@anysphere/file-service-linux-x64-gnu": "0.0.0-a75b800f",
46
+ "@anysphere/file-service-darwin-arm64": "0.0.0-a75b800f",
47
+ "@anysphere/file-service-win32-arm64-msvc": "0.0.0-a75b800f",
48
+ "@anysphere/file-service-darwin-universal": "0.0.0-a75b800f",
49
+ "@anysphere/file-service-linux-arm64-gnu": "0.0.0-a75b800f"
46
50
  }
47
51
  }
package/.yarnrc.yml DELETED
@@ -1 +0,0 @@
1
- nodeLinker: node-modules
package/Cargo.toml DELETED
@@ -1,43 +0,0 @@
1
- [package]
2
- edition = "2021"
3
- name = "file_service"
4
- version = "0.0.0"
5
-
6
- [lib]
7
- crate-type = ["cdylib"]
8
-
9
- [features]
10
- default = ["windows-subsystem"]
11
- windows-subsystem = []
12
- debugfile = []
13
-
14
- [dependencies]
15
- # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
16
- napi = { version = "2.12.2", default-features = false, features = ["napi4", "async", "tokio_rt"] }
17
- napi-derive = "2.12.2"
18
- tokio = { version = "1.32.0", features = ["process", "full"] }
19
- sha2 = "0.10.7"
20
- rand = "0.8.5"
21
- tempfile = "3.8.0"
22
- anyhow = "1.0.75"
23
- tonic = "0.9.2"
24
- prost = "0.11.9"
25
- tracing = "0.1.37"
26
- tracing-subscriber = "0.3.17"
27
- tracing-appender = "0.2.2"
28
- binaryornot = "1.0.0"
29
- dunce = "1.0.1"
30
- encoding_rs = "0.8.33"
31
-
32
- [target.'cfg(not(target_os = "linux"))'.dependencies]
33
- tracing-axiom = "0.4"
34
-
35
- [build-dependencies]
36
- napi-build = "2.0.1"
37
- tonic-build = "0.9.2"
38
- anyhow = "1.0.75"
39
- glob = "0.3.0"
40
-
41
-
42
- [profile.release]
43
- lto = true
package/build.rs DELETED
@@ -1,46 +0,0 @@
1
- use std::path::Path;
2
-
3
- extern crate napi_build;
4
-
5
- fn main() -> Result<(), anyhow::Error> {
6
- #[cfg(target_os = "windows")]
7
- println!("cargo:rustc-cdylib-link-arg=/SUBSYSTEM:WINDOWS");
8
- napi_build::setup();
9
-
10
- // print the relative path.
11
- // let workspace_root = "../../../../../";
12
- // let path = std::path::Path::new(workspace_root).canonicalize()?;
13
- // let include_path = Path::join(&path, "schema");
14
-
15
- // // let relevant_protos = &[
16
- // // "aiserver/v1/repository.proto",
17
- // // "aiserver/v1/symbolic_context.proto",
18
- // // "aiserver/v1/utils.proto"
19
- // // ];
20
- // // let proto_paths = relevant_protos
21
- // // .iter()
22
- // // .map(|proto| Path::join(&include_path, proto))
23
- // // .collect::<Vec<_>>();
24
- // let proto_glob = Path::join(&include_path, "aiserver/v1/*.proto");
25
- // let relevant_protos: Vec<_> = glob::glob(proto_glob.to_str().expect("Failed to convert path to str"))?
26
- // .filter_map(Result::ok)
27
- // .collect();
28
-
29
- // let proto_paths = relevant_protos
30
- // .iter()
31
- // .map(|proto_path| proto_path.to_str().expect("Failed to convert path to str"))
32
- // .collect::<Vec<_>>();
33
- // let includes = &[include_path.to_str().unwrap()];
34
-
35
- // // print the path
36
- // println!("cargo:rustc-env=INCLUDE_PATH={}", include_path.display());
37
-
38
- // tonic_build::configure()
39
- // .build_server(false)
40
- // .build_transport(true)
41
- // .out_dir("src/proto")
42
- // .compile(&proto_paths, includes)?;
43
-
44
-
45
- Ok(())
46
- }
package/src/file_utils.rs DELETED
@@ -1,328 +0,0 @@
1
- // what methods do i want to support here.
2
- // 1. isInBadDir
3
- // 2. isBadFile
4
- // 3. vscode.workspace.asRelativePath
5
- // 4. vscode.fs.stat
6
-
7
- use anyhow::Error;
8
- use encoding_rs::UTF_8;
9
- use std::path::Path;
10
- use tokio::fs;
11
-
12
- pub fn is_in_bad_dir(file_path: &Path) -> Result<bool, Error> {
13
- let item_path = file_path
14
- .to_str()
15
- .ok_or(anyhow::anyhow!("Failed to convert path to string"))?;
16
- let is_bad_dir =
17
- item_path.contains("node_modules") || item_path.contains(".git");
18
- Ok(is_bad_dir)
19
- }
20
-
21
- pub fn is_good_file(file_path: &Path) -> Result<(), Error> {
22
- let item_path = file_path
23
- .to_str()
24
- .ok_or(anyhow::anyhow!("Failed to convert path to string"))?;
25
-
26
- let path = Path::new(item_path);
27
- let file_name = path
28
- .file_name()
29
- .ok_or(anyhow::anyhow!("Failed to get file name"))?
30
- .to_str()
31
- .ok_or(anyhow::anyhow!("Failed to convert file name to string"))?;
32
-
33
- let extension = path
34
- .extension()
35
- .ok_or(anyhow::anyhow!("Failed to get extension"))?
36
- .to_str()
37
- .ok_or(anyhow::anyhow!("Failed to convert extension to string"))?;
38
-
39
- match file_name {
40
- "package-lock.json" | "pnpm-lock.yaml" | "yarn.lock" | "composer.lock"
41
- | "Gemfile.lock" | "bun.lockb" => {
42
- return Err(anyhow::anyhow!("File is just a lock file"));
43
- }
44
- _ => {}
45
- }
46
-
47
- let bad_extensions = vec![
48
- "lock",
49
- "bak",
50
- "tmp",
51
- "bin",
52
- "exe",
53
- "dll",
54
- "so",
55
- "lockb",
56
- "qwoff",
57
- "isl",
58
- "csv",
59
- "pdf",
60
- // add ms word, excel, powerpoint, etc.
61
- "doc",
62
- "docx",
63
- "xls",
64
- "xlsx",
65
- "ppt",
66
- "pptx",
67
- "odt",
68
- "ods",
69
- "odp",
70
- "odg",
71
- "odf",
72
- "sxw",
73
- "sxc",
74
- "sxi",
75
- "sxd",
76
- "sdc",
77
- // add images
78
- "jpg",
79
- "jpeg",
80
- "png",
81
- "gif",
82
- "bmp",
83
- "tif",
84
- // add audio
85
- "mp3",
86
- "wav",
87
- "wma",
88
- "ogg",
89
- "flac",
90
- "aac",
91
- // add video
92
- "mp4",
93
- "mov",
94
- "wmv",
95
- "flv",
96
- "avi",
97
- // add archives
98
- "zip",
99
- "tar",
100
- "gz",
101
- "7z",
102
- "rar",
103
- "tgz",
104
- "dmg",
105
- "iso",
106
- "cue",
107
- "mdf",
108
- "mds",
109
- "vcd",
110
- "toast",
111
- "img",
112
- "apk",
113
- "msi",
114
- "cab",
115
- "tar.gz",
116
- "tar.xz",
117
- "tar.bz2",
118
- "tar.lzma",
119
- "tar.Z",
120
- "tar.sz",
121
- "lzma",
122
- // add fonts
123
- "ttf",
124
- "otf",
125
- "woff",
126
- "woff2",
127
- "eot",
128
- ];
129
- match bad_extensions.contains(&extension) {
130
- true => {
131
- return Err(anyhow::anyhow!("File is just a lock file"));
132
- }
133
- _ => {}
134
- }
135
-
136
- if item_path.contains(".git")
137
- || item_path.contains(".svn")
138
- || item_path.contains(".hg")
139
- {
140
- return Err(anyhow::anyhow!("File is just a lock file"));
141
- }
142
-
143
- let bad_extensions = vec![".exe", ".dll", ".so", ".o", ".bin"];
144
- match Path::new(item_path).extension() {
145
- Some(extension) => match extension.to_str() {
146
- Some(ext_str) => {
147
- if bad_extensions.contains(&ext_str) {
148
- return Err(anyhow::anyhow!("Binary file excluded from indexing."));
149
- }
150
- }
151
- None => {
152
- return Err(anyhow::anyhow!("Failed to convert extension to string"))
153
- }
154
- },
155
- None => return Err(anyhow::anyhow!("Failed to get extension")),
156
- }
157
-
158
- // #[cfg(not(test))]
159
- // {
160
- let path = Path::new(item_path);
161
- for part in path.iter() {
162
- match part.to_str() {
163
- Some(s) if s.starts_with(".") => {
164
- return Err(anyhow::anyhow!("File is hidden"))
165
- }
166
- _ => {}
167
- }
168
- }
169
- // }
170
-
171
- Ok(())
172
- }
173
-
174
- // use binaryornot::is_binary;
175
- // use anyhow::Context;
176
- // implement the buffer above:
177
- pub async fn is_good_file_runtime_check(
178
- file_path: &Path,
179
- // _buffer: &[u8],
180
- ) -> Result<(), Error> {
181
- match get_file_size(file_path).await {
182
- Ok(size) if size > 2 * 1024 * 1024 => {
183
- return Err(anyhow::anyhow!("Buffer is too large"));
184
- }
185
- Err(e) => return Err(e),
186
- _ => {}
187
- }
188
-
189
- // if is_binary(file_path).context("Failed to check if file is binary")? {
190
- // return Err(anyhow::anyhow!("File is binary"));
191
- // }
192
-
193
- Ok(())
194
- }
195
-
196
- pub async fn read_string_without_bom(
197
- file_path: &Path,
198
- ) -> Result<String, Error> {
199
- let file_buffer = match fs::read(file_path).await {
200
- Ok(buffer) => buffer,
201
- Err(e) => {
202
- return Err(anyhow::anyhow!(
203
- "Failed to read file buffer: {}",
204
- e.to_string()
205
- ))
206
- }
207
- };
208
-
209
- let (cow, _) = UTF_8.decode_with_bom_removal(&file_buffer);
210
-
211
- Ok(cow.to_string())
212
- }
213
-
214
- pub fn as_relative_path(
215
- base_path: &Path,
216
- file_path: &Path,
217
- ) -> Result<String, Error> {
218
- let relative_path = file_path.strip_prefix(base_path)?;
219
- Ok(
220
- relative_path
221
- .to_str()
222
- .ok_or(anyhow::anyhow!("Failed to convert relative path to string"))?
223
- .to_string(),
224
- )
225
- }
226
-
227
- pub async fn get_file_size(file_path: &Path) -> Result<u64, Error> {
228
- let metadata = fs::metadata(file_path).await?;
229
-
230
- Ok(metadata.len())
231
- }
232
-
233
- #[cfg(test)]
234
- mod tests {
235
- use super::*;
236
- use std::path::Path;
237
- use tokio::io::AsyncWriteExt;
238
-
239
- #[test]
240
- fn test_is_in_bad_dir() {
241
- let path = Path::new("src/node_modules/test.rs");
242
- assert_eq!(is_in_bad_dir(&path).unwrap(), true);
243
-
244
- let path = Path::new("src/.git/test.rs");
245
- assert_eq!(is_in_bad_dir(&path).unwrap(), true);
246
-
247
- let path = Path::new("src/test.rs");
248
- assert_eq!(is_in_bad_dir(&path).unwrap(), false);
249
- }
250
-
251
- #[test]
252
- fn test_is_good_file() {
253
- let path = Path::new("src/test.rs");
254
- assert_eq!(is_good_file(&path).is_ok(), true);
255
-
256
- let path = Path::new("src/test.exe");
257
- assert_eq!(is_good_file(&path).is_err(), true);
258
-
259
- let path = Path::new("src/.hidden");
260
- assert_eq!(is_good_file(&path).is_err(), true);
261
- }
262
-
263
- #[tokio::test]
264
- async fn test_is_good_file_runtime_check() {
265
- let temp_dir = tempfile::tempdir().unwrap();
266
- let temp_file_path = temp_dir.path().join("test_file");
267
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
268
- temp_file.write_all(b"Hello, world!").await.unwrap();
269
- let buffer = fs::read(&temp_file_path).await.unwrap();
270
- assert_eq!(
271
- is_good_file_runtime_check(&temp_file_path).await.is_ok(),
272
- true
273
- );
274
- temp_dir.close().unwrap();
275
-
276
- // let temp_dir = tempfile::tempdir().unwrap();
277
- // let temp_file_path = temp_dir.path().join("test_file");
278
- // let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
279
- // temp_file.write_all(&[0, 159, 146, 150]).await.unwrap(); // Invalid UTF-8 sequence
280
- // let buffer = fs::read(&temp_file_path).await.unwrap();
281
- // assert_eq!(
282
- // is_good_file_runtime_check(&temp_file_path).await.is_err(),
283
- // true
284
- // );
285
- // temp_dir.close().unwrap();
286
- }
287
-
288
- #[tokio::test]
289
- async fn test_bom_file() {
290
- const BOM: [u8; 3] = [0xEF, 0xBB, 0xBF];
291
- const CONTENT: &str = "Hello, world!";
292
-
293
- // Write this to a temp file
294
- let temp_dir = tempfile::tempdir().unwrap();
295
- let temp_file_path = temp_dir.path().join("test_file");
296
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
297
- temp_file.write_all(&BOM).await.unwrap();
298
- temp_file.write_all(CONTENT.as_bytes()).await.unwrap();
299
-
300
- // expect that we read the file with tokio as the CONTENT
301
- let file_contents = read_string_without_bom(&temp_file_path).await.unwrap();
302
-
303
- // Check string equality of CONTENT (&str) to file_contents (String)
304
- assert_eq!(CONTENT, file_contents);
305
- }
306
-
307
- #[test]
308
- fn test_as_relative_path() {
309
- let base_path = Path::new("/home/user/src");
310
- let file_path = Path::new("/home/user/src/test.rs");
311
- assert_eq!(as_relative_path(&base_path, &file_path).unwrap(), "test.rs");
312
-
313
- let file_path = Path::new("/home/user/test.rs");
314
- assert!(as_relative_path(&base_path, &file_path).is_err());
315
- }
316
-
317
- #[tokio::test]
318
- async fn test_get_file_size() {
319
- let temp_dir = tempfile::tempdir().unwrap();
320
- let temp_file_path = temp_dir.path().join("test_file.txt");
321
- let mut temp_file = fs::File::create(&temp_file_path).await.unwrap();
322
- temp_file.write_all(b"Hello, world!").await.unwrap();
323
-
324
- let size = get_file_size(&temp_file_path).await.unwrap();
325
- assert_eq!(size, 13);
326
- temp_dir.close().unwrap();
327
- }
328
- }