@anysphere/file-service 0.0.0-ebd74baa → 0.0.0-ec067eac

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,94 @@
3
3
 
4
4
  /* auto-generated by NAPI-RS */
5
5
 
6
- export class MerkleClient {
6
+ export const enum DiffType {
7
+ Insert = 'Insert',
8
+ Delete = 'Delete',
9
+ Equal = 'Equal'
10
+ }
11
+ export interface DiffChunk {
12
+ diffType: DiffType
13
+ text: string
14
+ }
15
+ export interface WalkDirConfig {
16
+ maxNumFiles: number
17
+ logFilePath?: string
18
+ blocklistPath?: string
19
+ }
20
+ export interface CommitData {
21
+ sha: string
22
+ date: number
23
+ message: string
24
+ author: string
25
+ parents: Array<string>
26
+ files: Array<CommitFile>
27
+ }
28
+ export interface CommitFile {
29
+ from: string
30
+ to: string
31
+ additions: number
32
+ deletions: number
33
+ status: CommitFileStatus
34
+ }
35
+ export const enum CommitFileStatus {
36
+ Added = 0,
37
+ Deleted = 1,
38
+ Modified = 2,
39
+ Renamed = 3
40
+ }
41
+ export const enum CommitChainGetFiles {
42
+ DoGetFiles = 0,
43
+ DontGetFiles = 1
44
+ }
45
+ export interface VerifyData {
46
+ commitTime: number
47
+ fileContent: string
48
+ filePath: string
49
+ }
50
+ export interface Candidate {
51
+ path: string
52
+ locations: Array<number>
53
+ weight: number
54
+ }
55
+ export declare class DiffClient {
56
+ constructor()
57
+ diff(text1: string, text2: string): Array<DiffChunk>
58
+ /**
59
+ * use https://docs.rs/diffmatchpatch/latest/diffmatchpatch/struct.DiffMatchPatch.html#method.diff_lines_to_chars
60
+ * then diff the chars.
61
+ * then convert back to lines.
62
+ *
63
+ * takes in two strings. splits based on newlines.
64
+ * returns diffs based on lines.
65
+ */
66
+ diffLines(text1: string, text2: string): Array<DiffChunk>
67
+ }
68
+ export declare class MerkleClient {
7
69
  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>
70
+ build(allowIncremental: boolean, config: WalkDirConfig): Promise<void>
12
71
  getSubtreeHash(relativePath: string): Promise<string>
13
72
  getNumEmbeddableFiles(): Promise<number>
73
+ getImportantPaths(k: number): Promise<Array<string>>
14
74
  getAllFiles(): Promise<Array<string>>
15
75
  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
76
+ onDidCreate(absoluteFilePath: string): void
77
+ onDidChange(absoluteFilePath: string): void
78
+ onDidDelete(absoluteFilePath: string): void
79
+ static enableTracing(): void
80
+ }
81
+ export declare class GitClient {
82
+ constructor(absoluteRootDirectory: string)
83
+ getTotalCommitCount(): Promise<number>
84
+ getCommitVerifyData(commit: string): Promise<VerifyData>
85
+ throwIfCommitDoesntExist(rootSha: string): Promise<void>
86
+ getVerifyCommit(): Promise<string>
87
+ getRepoHeadSha(): Promise<string | null>
88
+ getCommitChain(hash: string, depth: number, getFiles: CommitChainGetFiles): Promise<Array<CommitData>>
89
+ }
90
+ export declare class GitFile {
91
+ findSimilarFiles(lineno: number): Promise<Array<Candidate>>
92
+ }
93
+ export declare class LocalGitGraph {
94
+ constructor(repo: string)
95
+ openFile(path: string): Promise<GitFile>
20
96
  }
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,13 @@ if (!nativeBinding) {
252
310
  throw new Error(`Failed to load native binding`)
253
311
  }
254
312
 
255
- const { MerkleClient } = nativeBinding
313
+ const { DiffType, DiffClient, MerkleClient, GitClient, CommitFileStatus, CommitChainGetFiles, GitFile, LocalGitGraph } = nativeBinding
256
314
 
315
+ module.exports.DiffType = DiffType
316
+ module.exports.DiffClient = DiffClient
257
317
  module.exports.MerkleClient = MerkleClient
318
+ module.exports.GitClient = GitClient
319
+ module.exports.CommitFileStatus = CommitFileStatus
320
+ module.exports.CommitChainGetFiles = CommitChainGetFiles
321
+ module.exports.GitFile = GitFile
322
+ 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-ebd74baa",
3
+ "version": "0.0.0-ec067eac",
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-ebd74baa",
40
- "@anysphere/file-service-darwin-x64": "0.0.0-ebd74baa",
41
- "@anysphere/file-service-linux-x64-gnu": "0.0.0-ebd74baa",
42
- "@anysphere/file-service-darwin-arm64": "0.0.0-ebd74baa",
43
- "@anysphere/file-service-win32-arm64-msvc": "0.0.0-ebd74baa",
44
- "@anysphere/file-service-darwin-universal": "0.0.0-ebd74baa",
45
- "@anysphere/file-service-linux-arm64-gnu": "0.0.0-ebd74baa"
43
+ "@anysphere/file-service-win32-x64-msvc": "0.0.0-ec067eac",
44
+ "@anysphere/file-service-darwin-x64": "0.0.0-ec067eac",
45
+ "@anysphere/file-service-linux-x64-gnu": "0.0.0-ec067eac",
46
+ "@anysphere/file-service-darwin-arm64": "0.0.0-ec067eac",
47
+ "@anysphere/file-service-win32-arm64-msvc": "0.0.0-ec067eac",
48
+ "@anysphere/file-service-darwin-universal": "0.0.0-ec067eac",
49
+ "@anysphere/file-service-linux-arm64-gnu": "0.0.0-ec067eac"
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
- }