Skip to content

Commit

Permalink
feat(fs): add the size method to get the size of a file or directory.
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Nov 25, 2024
1 parent 51cd283 commit 6e1d116
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 2 deletions.
1 change: 1 addition & 0 deletions plugins/fs/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ const COMMANDS: &[(&str, &[&str])] = &[
("exists", &[]),
("watch", &[]),
("unwatch", &[]),
("size", &[]),
];

fn main() {
Expand Down
25 changes: 24 additions & 1 deletion plugins/fs/guest-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,28 @@ async function watchImmediate(
}
}

/**
* Get the size of a file or directory.
* @example
* ```typescript
* import { size, BaseDirectory } from '@tauri-apps/plugin-fs';
* // Get the size of the `$APPDATA/tauri` directory.
* const dirSize = await size('tauri', { baseDir: BaseDirectory.AppData });
* console.log(dirSize); // 1024
* ```
*
* @since 2.0.0
*/
async function size(path: string | URL): Promise<number> {
if (path instanceof URL && path.protocol !== 'file:') {
throw new TypeError('Must be a file URL.')
}

return await invoke('plugin:fs|size', {
path: path instanceof URL ? path.toString() : path,
})
}

export type {
CreateOptions,
OpenOptions,
Expand Down Expand Up @@ -1369,5 +1391,6 @@ export {
writeTextFile,
exists,
watch,
watchImmediate
watchImmediate,
size
}
13 changes: 13 additions & 0 deletions plugins/fs/permissions/autogenerated/commands/size.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Automatically generated - DO NOT EDIT!

"$schema" = "../../schemas/schema.json"

[[permission]]
identifier = "allow-size"
description = "Enables the size command without any pre-configured scope."
commands.allow = ["size"]

[[permission]]
identifier = "deny-size"
description = "Denies the size command without any pre-configured scope."
commands.deny = ["size"]
26 changes: 26 additions & 0 deletions plugins/fs/permissions/autogenerated/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -3410,6 +3410,32 @@ Denies the seek command without any pre-configured scope.
<tr>
<td>

`fs:allow-size`

</td>
<td>

Enables the size command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`fs:deny-size`

</td>
<td>

Denies the size command without any pre-configured scope.

</td>
</tr>

<tr>
<td>

`fs:allow-stat`

</td>
Expand Down
2 changes: 1 addition & 1 deletion plugins/fs/permissions/read-meta.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
[[permission]]
identifier = "read-meta"
description = "This enables all index or metadata related commands without any pre-configured accessible paths."
commands.allow = ["read_dir", "stat", "lstat", "fstat", "exists"]
commands.allow = ["read_dir", "stat", "lstat", "fstat", "exists", "size"]
10 changes: 10 additions & 0 deletions plugins/fs/permissions/schemas/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -1589,6 +1589,16 @@
"type": "string",
"const": "deny-seek"
},
{
"description": "Enables the size command without any pre-configured scope.",
"type": "string",
"const": "allow-size"
},
{
"description": "Denies the size command without any pre-configured scope.",
"type": "string",
"const": "deny-size"
},
{
"description": "Enables the stat command without any pre-configured scope.",
"type": "string",
Expand Down
50 changes: 50 additions & 0 deletions plugins/fs/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT

use anyhow::Ok;
use serde::{Deserialize, Serialize, Serializer};
use serde_repr::{Deserialize_repr, Serialize_repr};
use tauri::{
Expand Down Expand Up @@ -897,6 +898,55 @@ pub fn exists<R: Runtime>(
Ok(resolved_path.exists())
}

#[tauri::command]
pub async fn size<R: Runtime>(
webview: Webview<R>,
global_scope: GlobalScope<Entry>,
command_scope: CommandScope<Entry>,
path: SafeFilePath,
options: Option<BaseOptions>,
) -> CommandResult<u64> {
let resolved_path = resolve_path(
&webview,
&global_scope,
&command_scope,
path,
options.as_ref().and_then(|o| o.base_dir),
)?;

let metadata = resolved_path.metadata()?;

if metadata.is_file() {
Ok(metadata.len())
} else {
let size = get_dir_size(resolved_path).map_err(|e| {
format!(
"failed to get size at path: {} with error: {e}",
resolved_path.display()
)
})?;

Ok(size)
}
}

fn get_dir_size(path: PathBuf) -> CommandResult<u64> {
let mut size = 0;

for entry in std::fs::read_dir(path)? {
let entry = entry?;
let metadata = entry.metadata()?;

if metadata.is_file() {
size += metadata.len();
} else if metadata.is_dir() {
size += get_dir_size(entry.path())?;
}
}

Ok(size)
}

#[cfg(not(target_os = "android"))]
pub fn resolve_file<R: Runtime>(
webview: &Webview<R>,
Expand Down

0 comments on commit 6e1d116

Please sign in to comment.