Skip to content

Commit 6e1d116

Browse files
committed
feat(fs): add the size method to get the size of a file or directory.
1 parent 51cd283 commit 6e1d116

File tree

7 files changed

+125
-2
lines changed

7 files changed

+125
-2
lines changed

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: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,28 @@ async function watchImmediate(
13221322
}
13231323
}
13241324

1325+
/**
1326+
* Get the size of a file or directory.
1327+
* @example
1328+
* ```typescript
1329+
* import { size, BaseDirectory } from '@tauri-apps/plugin-fs';
1330+
* // Get the size of the `$APPDATA/tauri` directory.
1331+
* const dirSize = await size('tauri', { baseDir: BaseDirectory.AppData });
1332+
* console.log(dirSize); // 1024
1333+
* ```
1334+
*
1335+
* @since 2.0.0
1336+
*/
1337+
async function size(path: string | URL): Promise<number> {
1338+
if (path instanceof URL && path.protocol !== 'file:') {
1339+
throw new TypeError('Must be a file URL.')
1340+
}
1341+
1342+
return await invoke('plugin:fs|size', {
1343+
path: path instanceof URL ? path.toString() : path,
1344+
})
1345+
}
1346+
13251347
export type {
13261348
CreateOptions,
13271349
OpenOptions,
@@ -1369,5 +1391,6 @@ export {
13691391
writeTextFile,
13701392
exists,
13711393
watch,
1372-
watchImmediate
1394+
watchImmediate,
1395+
size
13731396
}
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: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0
44
// SPDX-License-Identifier: MIT
55

6+
use anyhow::Ok;
67
use serde::{Deserialize, Serialize, Serializer};
78
use serde_repr::{Deserialize_repr, Serialize_repr};
89
use tauri::{
@@ -897,6 +898,55 @@ pub fn exists<R: Runtime>(
897898
Ok(resolved_path.exists())
898899
}
899900

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

0 commit comments

Comments
 (0)