diff options
| -rw-r--r-- | filamento/Cargo.toml | 2 | ||||
| -rw-r--r-- | filamento/src/chat.rs | 16 | ||||
| -rw-r--r-- | filamento/src/db.rs | 12 | ||||
| -rw-r--r-- | filamento/src/error.rs | 2 | ||||
| -rw-r--r-- | filamento/src/files.rs | 25 | 
5 files changed, 56 insertions, 1 deletions
| diff --git a/filamento/Cargo.toml b/filamento/Cargo.toml index 65ebcf4..08f482b 100644 --- a/filamento/Cargo.toml +++ b/filamento/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024"  [features]  serde = ["dep:serde", "jid/serde", "uuid/serde", "chrono/serde", "lampada/serde"] +opfs = ["dep:web-sys"]  reactive_stores = ["dep:reactive_stores"]  [dependencies] @@ -32,6 +33,7 @@ reactive_stores = { version = "0.1.8", optional = true }  tokio = { workspace = true, features = ["sync", "time", "rt", "fs", "io-std"] }  [target.'cfg(target_arch = "wasm32")'.dependencies] +web-sys = { version = "0.3", features = ["FileSystemDirectoryHandle", "FileSystemWritableFileStream", "FileSystemGetDirectoryOptions", "FileSystemFileHandle", "StorageManager", "File", "Url", "Window", "Navigator"], optional = true }  jid = { version = "0.1.0", path = "../jid", features = ["rusqlite"] }  wasm-bindgen = "0.2"  wasm-bindgen-futures = "0.4" diff --git a/filamento/src/chat.rs b/filamento/src/chat.rs index bb0793f..5f58866 100644 --- a/filamento/src/chat.rs +++ b/filamento/src/chat.rs @@ -1,3 +1,5 @@ +use std::fmt::{Display, Write}; +  use chrono::{DateTime, Utc};  use jid::JID;  use rusqlite::{ @@ -34,6 +36,20 @@ pub enum Delivery {      Queued,  } +impl Display for Delivery { +    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +        match self { +            Delivery::Sending => f.write_str("sending"), +            Delivery::Written => f.write_str("written"), +            Delivery::Sent => f.write_str("sent"), +            Delivery::Delivered => f.write_str("delivered"), +            Delivery::Read => f.write_str("read"), +            Delivery::Failed => f.write_str("failed"), +            Delivery::Queued => f.write_str("queued"), +        } +    } +} +  impl ToSql for Delivery {      fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {          Ok(match self { diff --git a/filamento/src/db.rs b/filamento/src/db.rs index d2c24a2..e560443 100644 --- a/filamento/src/db.rs +++ b/filamento/src/db.rs @@ -55,9 +55,21 @@ impl Db {      }      #[cfg(target_arch = "wasm32")] +    pub async fn create_connect_and_migrate_memory() -> Result<Self, DatabaseOpenError> { +        let db = Connection::open("mem.db")?; +        db.execute_batch(include_str!("../migrations/1.sql"))?; +        Ok(Self { +            db: Arc::new(Mutex::new(db)), +        }) +    } + +    #[cfg(target_arch = "wasm32")]      pub async fn create_connect_and_migrate(          path: impl AsRef<Path>,      ) -> Result<Self, DatabaseOpenError> { +        // rusqlite::ffi::install_opfs_sahpool(Some(&rusqlite::ffi::OpfsSAHPoolCfg::default()), true) +        //     .await +        //     .unwrap();          let db = Connection::open(path)?;          db.execute_batch(include_str!("../migrations/1.sql"))?;          Ok(Self { diff --git a/filamento/src/error.rs b/filamento/src/error.rs index bf28160..02f54ee 100644 --- a/filamento/src/error.rs +++ b/filamento/src/error.rs @@ -4,7 +4,7 @@ use base64::DecodeError;  use image::ImageError;  use jid::JID;  use lampada::error::{ActorError, ReadError, WriteError}; -use stanza::client::{iq::Query, Stanza}; +use stanza::client::{Stanza, iq::Query};  use thiserror::Error;  pub use lampada::error::CommandError; diff --git a/filamento/src/files.rs b/filamento/src/files.rs index 644f883..dcc9cd2 100644 --- a/filamento/src/files.rs +++ b/filamento/src/files.rs @@ -9,6 +9,7 @@ use std::{  use tokio::io;  use tokio::sync::Mutex; +#[cfg(not(target_arch = "wasm32"))]  pub trait FileStore {      type Err: Clone + Send + Error; @@ -27,6 +28,19 @@ pub trait FileStore {      ) -> impl std::future::Future<Output = Result<(), Self::Err>> + std::marker::Send;  } +#[cfg(target_arch = "wasm32")] +pub trait FileStore { +    type Err: Clone + Send + Error; + +    fn is_stored(&self, name: &str) -> impl std::future::Future<Output = Result<bool, Self::Err>>; +    fn store( +        &self, +        name: &str, +        data: &[u8], +    ) -> impl std::future::Future<Output = Result<(), Self::Err>>; +    fn delete(&self, name: &str) -> impl std::future::Future<Output = Result<(), Self::Err>>; +} +  #[derive(Clone, Debug)]  pub struct FilesMem {      files: Arc<Mutex<HashMap<String, Vec<u8>>>>, @@ -38,8 +52,19 @@ impl FilesMem {              files: Arc::new(Mutex::new(HashMap::new())),          }      } + +    pub async fn get_file(&self, name: impl AsRef<str>) -> Option<Vec<u8>> { +        let name = name.as_ref(); +        self.files.lock().await.get(name).cloned() +    }  } +#[cfg(all(feature = "opfs", target_arch = "wasm32"))] +pub mod opfs; + +#[cfg(all(feature = "opfs", target_arch = "wasm32"))] +pub use opfs::FilesOPFS; +  impl FileStore for FilesMem {      type Err = Infallible; | 
