file_upload.rs 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. use std::{path::PathBuf, str::FromStr};
  2. use serde::Deserialize;
  3. #[derive(Debug, Deserialize)]
  4. pub(crate) struct FileDiologRequest {
  5. accept: String,
  6. multiple: bool,
  7. pub event: String,
  8. pub target: usize,
  9. pub bubbles: bool,
  10. }
  11. pub(crate) fn get_file_event(request: &FileDiologRequest) -> Vec<PathBuf> {
  12. let mut dialog = rfd::FileDialog::new();
  13. let filters: Vec<_> = request
  14. .accept
  15. .split(',')
  16. .filter_map(|s| Filters::from_str(s).ok())
  17. .collect();
  18. let file_extensions: Vec<_> = filters
  19. .iter()
  20. .flat_map(|f| f.as_extensions().into_iter())
  21. .collect();
  22. dialog = dialog.add_filter("name", file_extensions.as_slice());
  23. let files: Vec<_> = if request.multiple {
  24. dialog.pick_files().into_iter().flatten().collect()
  25. } else {
  26. dialog.pick_file().into_iter().collect()
  27. };
  28. files
  29. }
  30. enum Filters {
  31. Extension(String),
  32. Mime(String),
  33. Audio,
  34. Video,
  35. Image,
  36. }
  37. impl Filters {
  38. fn as_extensions(&self) -> Vec<&str> {
  39. match self {
  40. Filters::Extension(extension) => vec![extension.as_str()],
  41. Filters::Mime(_) => vec![],
  42. Filters::Audio => vec!["mp3", "wav", "ogg"],
  43. Filters::Video => vec!["mp4", "webm"],
  44. Filters::Image => vec!["png", "jpg", "jpeg", "gif", "webp"],
  45. }
  46. }
  47. }
  48. impl FromStr for Filters {
  49. type Err = String;
  50. fn from_str(s: &str) -> Result<Self, Self::Err> {
  51. if let Some(extension) = s.strip_prefix('.') {
  52. Ok(Filters::Extension(extension.to_string()))
  53. } else {
  54. match s {
  55. "audio/*" => Ok(Filters::Audio),
  56. "video/*" => Ok(Filters::Video),
  57. "image/*" => Ok(Filters::Image),
  58. _ => Ok(Filters::Mime(s.to_string())),
  59. }
  60. }
  61. }
  62. }