pub struct FileDialogBuilder(_);
Available on desktop and crate feature dialog only.
Expand description

The file dialog builder.

Constructs file picker dialogs that can select single/multiple files or directories.

Implementations§

Gets the default file dialog builder.

Examples found in repository?
src/endpoints/dialog.rs (line 166)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

  #[module_command_handler(dialog_save)]
  #[allow(unused_variables)]
  fn save_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: SaveDialogOptions,
  ) -> super::Result<Option<PathBuf>> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let path = dialog_builder.save_file();
    if let Some(p) = &path {
      scopes.allow_file(p).map_err(crate::error::into_anyhow)?;
    }

    Ok(path)
  }

Add file extension filter. Takes in the name of the filter, and list of extensions

Examples found in repository?
src/endpoints/dialog.rs (line 179)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

  #[module_command_handler(dialog_save)]
  #[allow(unused_variables)]
  fn save_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: SaveDialogOptions,
  ) -> super::Result<Option<PathBuf>> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let path = dialog_builder.save_file();
    if let Some(p) = &path {
      scopes.allow_file(p).map_err(crate::error::into_anyhow)?;
    }

    Ok(path)
  }

Set starting directory of the dialog.

Examples found in repository?
src/endpoints/dialog.rs (line 282)
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
fn set_default_path(
  mut dialog_builder: FileDialogBuilder,
  default_path: PathBuf,
) -> FileDialogBuilder {
  if default_path.is_file() || !default_path.exists() {
    if let (Some(parent), Some(file_name)) = (default_path.parent(), default_path.file_name()) {
      if parent.components().count() > 0 {
        dialog_builder = dialog_builder.set_directory(parent);
      }
      dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy());
    } else {
      dialog_builder = dialog_builder.set_directory(default_path);
    }
    dialog_builder
  } else {
    dialog_builder.set_directory(default_path)
  }
}

Set starting file name of the dialog.

Examples found in repository?
src/endpoints/dialog.rs (line 284)
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
fn set_default_path(
  mut dialog_builder: FileDialogBuilder,
  default_path: PathBuf,
) -> FileDialogBuilder {
  if default_path.is_file() || !default_path.exists() {
    if let (Some(parent), Some(file_name)) = (default_path.parent(), default_path.file_name()) {
      if parent.components().count() > 0 {
        dialog_builder = dialog_builder.set_directory(parent);
      }
      dialog_builder = dialog_builder.set_file_name(&file_name.to_string_lossy());
    } else {
      dialog_builder = dialog_builder.set_directory(default_path);
    }
    dialog_builder
  } else {
    dialog_builder.set_directory(default_path)
  }
}

Sets the parent window of the dialog.

Examples found in repository?
src/endpoints/dialog.rs (line 169)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

  #[module_command_handler(dialog_save)]
  #[allow(unused_variables)]
  fn save_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: SaveDialogOptions,
  ) -> super::Result<Option<PathBuf>> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let path = dialog_builder.save_file();
    if let Some(p) = &path {
      scopes.allow_file(p).map_err(crate::error::into_anyhow)?;
    }

    Ok(path)
  }

Set the title of the dialog.

Examples found in repository?
src/endpoints/dialog.rs (line 172)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

  #[module_command_handler(dialog_save)]
  #[allow(unused_variables)]
  fn save_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: SaveDialogOptions,
  ) -> super::Result<Option<PathBuf>> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let path = dialog_builder.save_file();
    if let Some(p) = &path {
      scopes.allow_file(p).map_err(crate::error::into_anyhow)?;
    }

    Ok(path)
  }

Shows the dialog to select a single file. This is a blocking operation, and should NOT be used when running on the main thread context.

Examples
use tauri::api::dialog::blocking::FileDialogBuilder;
#[tauri::command]
fn my_command() {
  let file_path = FileDialogBuilder::new().pick_file();
  // do something with the optional file path here
  // the file path is `None` if the user closed the dialog
}
Examples found in repository?
src/endpoints/dialog.rs (line 213)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

Shows the dialog to select multiple files. This is a blocking operation, and should NOT be used when running on the main thread context.

Examples
use tauri::api::dialog::blocking::FileDialogBuilder;
#[tauri::command]
fn my_command() {
  let file_path = FileDialogBuilder::new().pick_files();
  // do something with the optional file paths here
  // the file paths value is `None` if the user closed the dialog
}
Examples found in repository?
src/endpoints/dialog.rs (line 205)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

Shows the dialog to select a single folder. This is a blocking operation, and should NOT be used when running on the main thread context.

Examples
use tauri::api::dialog::blocking::FileDialogBuilder;
#[tauri::command]
fn my_command() {
  let folder_path = FileDialogBuilder::new().pick_folder();
  // do something with the optional folder path here
  // the folder path is `None` if the user closed the dialog
}
Examples found in repository?
src/endpoints/dialog.rs (line 196)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

Shows the dialog to select multiple folders. This is a blocking operation, and should NOT be used when running on the main thread context.

Examples
use tauri::api::dialog::blocking::FileDialogBuilder;
#[tauri::command]
fn my_command() {
  let folder_paths = FileDialogBuilder::new().pick_folders();
  // do something with the optional folder paths here
  // the folder paths value is `None` if the user closed the dialog
}
Examples found in repository?
src/endpoints/dialog.rs (line 186)
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  fn open_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: OpenDialogOptions,
  ) -> super::Result<InvokeResponse> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let res = if options.directory {
      if options.multiple {
        let folders = dialog_builder.pick_folders();
        if let Some(folders) = &folders {
          for folder in folders {
            scopes
              .allow_directory(folder, options.recursive)
              .map_err(crate::error::into_anyhow)?;
          }
        }
        folders.into()
      } else {
        let folder = dialog_builder.pick_folder();
        if let Some(path) = &folder {
          scopes
            .allow_directory(path, options.recursive)
            .map_err(crate::error::into_anyhow)?;
        }
        folder.into()
      }
    } else if options.multiple {
      let files = dialog_builder.pick_files();
      if let Some(files) = &files {
        for file in files {
          scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
        }
      }
      files.into()
    } else {
      let file = dialog_builder.pick_file();
      if let Some(file) = &file {
        scopes.allow_file(file).map_err(crate::error::into_anyhow)?;
      }
      file.into()
    };

    Ok(res)
  }

Shows the dialog to save a file. This is a blocking operation, and should NOT be used when running on the main thread context.

Examples
use tauri::api::dialog::blocking::FileDialogBuilder;
#[tauri::command]
fn my_command() {
  let file_path = FileDialogBuilder::new().save_file();
  // do something with the optional file path here
  // the file path is `None` if the user closed the dialog
}
Examples found in repository?
src/endpoints/dialog.rs (line 247)
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  fn save_dialog<R: Runtime>(
    context: InvokeContext<R>,
    options: SaveDialogOptions,
  ) -> super::Result<Option<PathBuf>> {
    let mut dialog_builder = FileDialogBuilder::new();
    #[cfg(any(windows, target_os = "macos"))]
    {
      dialog_builder = dialog_builder.set_parent(&context.window);
    }
    if let Some(title) = options.title {
      dialog_builder = dialog_builder.set_title(&title);
    }
    if let Some(default_path) = options.default_path {
      dialog_builder = set_default_path(dialog_builder, default_path);
    }
    for filter in options.filters {
      let extensions: Vec<&str> = filter.extensions.iter().map(|s| &**s).collect();
      dialog_builder = dialog_builder.add_filter(filter.name, &extensions);
    }

    let scopes = context.window.state::<Scopes>();

    let path = dialog_builder.save_file();
    if let Some(p) = &path {
      scopes.allow_file(p).map_err(crate::error::into_anyhow)?;
    }

    Ok(path)
  }

Trait Implementations§

Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more