file_upload.rs 1.9 KB

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