Browse Source

FileEngine: expose native file types on different platforms (#1258)

* Get native file

* Correct visibility
wooden-worm 1 year ago
parent
commit
f652474a6e

+ 10 - 1
packages/html/src/events/form.rs

@@ -1,4 +1,4 @@
-use std::{collections::HashMap, fmt::Debug};
+use std::{any::Any, collections::HashMap, fmt::Debug};
 
 use dioxus_core::Event;
 
@@ -45,6 +45,12 @@ impl FileEngine for SerializedFileEngine {
             .await
             .map(|bytes| String::from_utf8_lossy(&bytes).to_string())
     }
+
+    async fn get_native_file(&self, file: &str) -> Option<Box<dyn Any>> {
+        self.read_file(file)
+            .await
+            .map(|val| Box::new(val) as Box<dyn Any>)
+    }
 }
 
 #[cfg(feature = "serialize")]
@@ -89,6 +95,9 @@ pub trait FileEngine {
 
     // read a file to string
     async fn read_file_to_string(&self, file: &str) -> Option<String>;
+
+    // returns a file in platform's native representation
+    async fn get_native_file(&self, file: &str) -> Option<Box<dyn Any>>;
 }
 
 impl_event! {

+ 6 - 0
packages/html/src/native_bind/native_file_engine.rs

@@ -1,3 +1,4 @@
+use std::any::Any;
 use std::path::PathBuf;
 
 use crate::FileEngine;
@@ -40,4 +41,9 @@ impl FileEngine for NativeFileEngine {
 
         Some(contents)
     }
+
+    async fn get_native_file(&self, file: &str) -> Option<Box<dyn Any>> {
+        let file = File::open(file).await.ok()?;
+        Some(Box::new(file))
+    }
 }

+ 23 - 0
packages/web/src/file_engine.rs

@@ -1,3 +1,5 @@
+use std::any::Any;
+
 use dioxus_html::FileEngine;
 use futures_channel::oneshot;
 use js_sys::Uint8Array;
@@ -100,4 +102,25 @@ impl FileEngine for WebFileEngine {
             None
         }
     }
+
+    async fn get_native_file(&self, file: &str) -> Option<Box<dyn Any>> {
+        let file = self.find(file)?;
+        Some(Box::new(file))
+    }
+}
+
+/// Helper trait for WebFileEngine
+#[async_trait::async_trait(?Send)]
+pub trait WebFileEngineExt {
+    /// returns web_sys::File
+    async fn get_web_file(&self, file: &str) -> Option<web_sys::File>;
+}
+
+#[async_trait::async_trait(?Send)]
+impl WebFileEngineExt for std::sync::Arc<dyn FileEngine> {
+    async fn get_web_file(&self, file: &str) -> Option<web_sys::File> {
+        let native_file = self.get_native_file(file).await?;
+        let ret = native_file.downcast::<web_sys::File>().ok()?;
+        Some(*ret)
+    }
 }

+ 1 - 0
packages/web/src/lib.rs

@@ -54,6 +54,7 @@
 //     - Do DOM work in the next requestAnimationFrame callback
 
 pub use crate::cfg::Config;
+pub use crate::file_engine::WebFileEngineExt;
 use dioxus_core::{Element, Scope, VirtualDom};
 use futures_util::{
     future::{select, Either},