Skip to content

Commit fef76bd

Browse files
authored
feat(fs): add the size method to get the size of a file or directory (#2095)
1 parent f8f2eef commit fef76bd

File tree

10 files changed

+134
-3
lines changed

10 files changed

+134
-3
lines changed

.changes/add-fs-size.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fs: minor
3+
---
4+
5+
Add the `size` method to get the size of a file or directory.

plugins/fs/api-iife.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/fs/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const COMMANDS: &[(&str, &[&str])] = &[
102102
("exists", &[]),
103103
("watch", &[]),
104104
("unwatch", &[]),
105+
("size", &[]),
105106
];
106107

107108
fn main() {

plugins/fs/guest-js/index.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,31 @@ async function watchImmediate(
13221322
}
13231323
}
13241324

1325+
/**
1326+
* Get the size of a file or directory. For files, the `stat` functions can be used as well.
1327+
*
1328+
* If `path` is a directory, this function will recursively iterate over every file and every directory inside of `path` and therefore will be very time consuming if used on larger directories.
1329+
*
1330+
* @example
1331+
* ```typescript
1332+
* import { size, BaseDirectory } from '@tauri-apps/plugin-fs';
1333+
* // Get the size of the `$APPDATA/tauri` directory.
1334+
* const dirSize = await size('tauri', { baseDir: BaseDirectory.AppData });
1335+
* console.log(dirSize); // 1024
1336+
* ```
1337+
*
1338+
* @since 2.1.0
1339+
*/
1340+
async function size(path: string | URL): Promise<number> {
1341+
if (path instanceof URL && path.protocol !== 'file:') {
1342+
throw new TypeError('Must be a file URL.')
1343+
}
1344+
1345+
return await invoke('plugin:fs|size', {
1346+
path: path instanceof URL ? path.toString() : path
1347+
})
1348+
}
1349+
13251350
export type {
13261351
CreateOptions,
13271352
OpenOptions,
@@ -1369,5 +1394,6 @@ export {
13691394
writeTextFile,
13701395
exists,
13711396
watch,
1372-
watchImmediate
1397+
watchImmediate,
1398+
size
13731399
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Automatically generated - DO NOT EDIT!
2+
3+
"$schema" = "../../schemas/schema.json"
4+
5+
[[permission]]
6+
identifier = "allow-size"
7+
description = "Enables the size command without any pre-configured scope."
8+
commands.allow = ["size"]
9+
10+
[[permission]]
11+
identifier = "deny-size"
12+
description = "Denies the size command without any pre-configured scope."
13+
commands.deny = ["size"]

plugins/fs/permissions/autogenerated/reference.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,32 @@ Denies the seek command without any pre-configured scope.
34103410
<tr>
34113411
<td>
34123412

3413+
`fs:allow-size`
3414+
3415+
</td>
3416+
<td>
3417+
3418+
Enables the size command without any pre-configured scope.
3419+
3420+
</td>
3421+
</tr>
3422+
3423+
<tr>
3424+
<td>
3425+
3426+
`fs:deny-size`
3427+
3428+
</td>
3429+
<td>
3430+
3431+
Denies the size command without any pre-configured scope.
3432+
3433+
</td>
3434+
</tr>
3435+
3436+
<tr>
3437+
<td>
3438+
34133439
`fs:allow-stat`
34143440

34153441
</td>

plugins/fs/permissions/read-meta.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
[[permission]]
44
identifier = "read-meta"
55
description = "This enables all index or metadata related commands without any pre-configured accessible paths."
6-
commands.allow = ["read_dir", "stat", "lstat", "fstat", "exists"]
6+
commands.allow = ["read_dir", "stat", "lstat", "fstat", "exists", "size"]

plugins/fs/permissions/schemas/schema.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,16 @@
15891589
"type": "string",
15901590
"const": "deny-seek"
15911591
},
1592+
{
1593+
"description": "Enables the size command without any pre-configured scope.",
1594+
"type": "string",
1595+
"const": "allow-size"
1596+
},
1597+
{
1598+
"description": "Denies the size command without any pre-configured scope.",
1599+
"type": "string",
1600+
"const": "deny-size"
1601+
},
15921602
{
15931603
"description": "Enables the stat command without any pre-configured scope.",
15941604
"type": "string",

plugins/fs/src/commands.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,55 @@ pub fn exists<R: Runtime>(
897897
Ok(resolved_path.exists())
898898
}
899899

900+
#[tauri::command]
901+
pub async fn size<R: Runtime>(
902+
webview: Webview<R>,
903+
global_scope: GlobalScope<Entry>,
904+
command_scope: CommandScope<Entry>,
905+
path: SafeFilePath,
906+
options: Option<BaseOptions>,
907+
) -> CommandResult<u64> {
908+
let resolved_path = resolve_path(
909+
&webview,
910+
&global_scope,
911+
&command_scope,
912+
path,
913+
options.as_ref().and_then(|o| o.base_dir),
914+
)?;
915+
916+
let metadata = resolved_path.metadata()?;
917+
918+
if metadata.is_file() {
919+
Ok(metadata.len())
920+
} else {
921+
let size = get_dir_size(&resolved_path).map_err(|e| {
922+
format!(
923+
"failed to get size at path: {} with error: {e}",
924+
resolved_path.display()
925+
)
926+
})?;
927+
928+
Ok(size)
929+
}
930+
}
931+
932+
fn get_dir_size(path: &PathBuf) -> CommandResult<u64> {
933+
let mut size = 0;
934+
935+
for entry in std::fs::read_dir(path)? {
936+
let entry = entry?;
937+
let metadata = entry.metadata()?;
938+
939+
if metadata.is_file() {
940+
size += metadata.len();
941+
} else if metadata.is_dir() {
942+
size += get_dir_size(&entry.path())?;
943+
}
944+
}
945+
946+
Ok(size)
947+
}
948+
900949
#[cfg(not(target_os = "android"))]
901950
pub fn resolve_file<R: Runtime>(
902951
webview: &Webview<R>,

plugins/fs/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R, Option<config::Config>> {
417417
commands::write_file,
418418
commands::write_text_file,
419419
commands::exists,
420+
commands::size,
420421
#[cfg(feature = "watch")]
421422
watcher::watch,
422423
#[cfg(feature = "watch")]

0 commit comments

Comments
 (0)