Skip to content

Commit

Permalink
Removed State from App
Browse files Browse the repository at this point in the history
  • Loading branch information
alvinosh committed Jan 6, 2025
1 parent aded471 commit 99dceae
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 70 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ package-lock.json
yarn.lock

vite.config.js.timestamp-*
vite.config.ts.timestamp-*
vite.config.ts.timestamp-*

.drop-send-*
20 changes: 11 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ uniffi = { version = "0.28.0" }
rand.workspace = true
data-encoding = "2.6.0"
async-channel = "2.3.1"
tokio.workspace = true
tracing-subscriber = "0.3.19"

[build-dependencies]
uniffi = { version = "0.28.0", features = ["build"] }
116 changes: 68 additions & 48 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,17 @@ use metadata::{CollectionMetadata, FileTransfer};

use rand::Rng;

pub struct IrohInstance {
router: Router,

blobs: Blobs<Store>,
}
pub struct IrohInstance {}

impl IrohInstance {
pub async fn new() -> Result<Self, Error> {
pub async fn send_files(files: Vec<String>) -> Result<BlobTicket, Error> {
let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap();
let local_pool = LocalPool::default();

let suffix = rand::thread_rng().gen::<[u8; 16]>();
let cwd = std::env::current_dir()?;
let blobs_data_dir = cwd.join(format!(".drop-send-{}", HEXLOWER.encode(&suffix)));

let blobs = Blobs::persistent(blobs_data_dir)
.await
.unwrap()
Expand All @@ -49,38 +46,44 @@ impl IrohInstance {
.await
.unwrap();

Ok(Self { router, blobs })
}

pub async fn send_files(&self, files: Vec<String>) -> Result<BlobTicket, Error> {
let paths: Vec<PathBuf> = files
.into_iter()
.map(|path| Ok(PathBuf::from_str(&path)?))
.filter_map(|path: Result<PathBuf, Error>| path.ok())
.collect();

let (hash, _tag) = self
.import_collection(paths)
let (hash, _tag) = IrohInstance::import_collection(blobs.clone(), paths)
.await
.expect("Failed to Import collection");

Ok(BlobTicket::new(
self.router.endpoint().node_id().into(),
router.endpoint().node_id().into(),
hash,
iroh_blobs::BlobFormat::HashSeq,
)
.expect("Failed to create ticket"))
}

pub async fn receive_files(&self, ticket: String) -> Result<Collection, Error> {
pub async fn receive_files(ticket: String) -> Result<Collection, Error> {
let endpoint = Endpoint::builder().discovery_n0().bind().await.unwrap();
let local_pool = LocalPool::default();

let suffix = rand::thread_rng().gen::<[u8; 16]>();
let cwd = std::env::current_dir()?;
let blobs_data_dir = cwd.join(format!(".drop-send-{}", HEXLOWER.encode(&suffix)));

let blobs = Blobs::persistent(blobs_data_dir)
.await
.unwrap()
.build(&local_pool, &endpoint);

let ticket = BlobTicket::from_str(&ticket).expect("Failed to parse ticket");

if ticket.format() != BlobFormat::HashSeq {
panic!("Invalid ticket format.");
}

let mut download = self
.blobs
let mut download = blobs
.client()
.download_hash_seq(ticket.hash(), ticket.node_addr().clone())
.await
Expand All @@ -95,8 +98,7 @@ impl IrohInstance {
if let Ok(event) = event {
match event {
DownloadProgress::FoundHashSeq { hash, .. } => {
let hashseq = self
.blobs
let hashseq = blobs
.client()
.read_to_bytes(hash)
.await
Expand All @@ -107,8 +109,7 @@ impl IrohInstance {

let metadata_hash =
hashseq.iter().next().expect("Failed to get metadata hash.");
let metadata_bytes = self
.blobs
let metadata_bytes = blobs
.client()
.read_to_bytes(metadata_hash)
.await
Expand All @@ -127,16 +128,14 @@ impl IrohInstance {
}

DownloadProgress::AllDone(_) => {
let collection = self
.blobs
let collection = blobs
.client()
.get_collection(ticket.hash())
.await
.expect("Failed to get collection.");
files = vec![];
for (name, hash) in collection.iter() {
let content = self
.blobs
let content = blobs
.client()
.read_to_bytes(*hash)
.await
Expand Down Expand Up @@ -230,8 +229,7 @@ impl IrohInstance {
}
}

let collection = self
.blobs
let collection = blobs
.client()
.get_collection(ticket.hash())
.await
Expand All @@ -240,27 +238,30 @@ impl IrohInstance {
Ok(collection.into())
}

pub async fn import_collection(&self, paths: Vec<PathBuf>) -> Result<(Hash, Tag), Error> {
let outcomes = try_join_all(paths.into_iter().map(|path| async move {
let add_progress = self
.blobs
.client()
.add_from_path(path.clone(), true, SetTagOption::Auto, WrapOption::NoWrap)
.await;

println!("Importing: {:?}", path);

match add_progress {
Ok(add_progress) => {
let outcome = add_progress.finish().await;
if let Ok(progress) = outcome {
Ok::<(PathBuf, AddOutcome), Error>((path.clone(), progress))
} else {
panic!("Failed to add blob: {:?}", outcome.err().unwrap())
pub async fn import_collection(
blobs: Blobs<Store>,
paths: Vec<PathBuf>,
) -> Result<(Hash, Tag), Error> {
let outcomes = try_join_all(paths.into_iter().map(|path| {
let blobs = blobs.clone();
async move {
let add_progress = blobs
.client()
.add_from_path(path.clone(), true, SetTagOption::Auto, WrapOption::NoWrap)
.await;

match add_progress {
Ok(add_progress) => {
let outcome = add_progress.finish().await;
if let Ok(progress) = outcome {
Ok::<(PathBuf, AddOutcome), Error>((path.clone(), progress))
} else {
panic!("Failed to add blob: {:?}", outcome.err().unwrap())
}
}
Err(e) => {
panic!("Failed to add blob: {:?}", e)
}
}
Err(e) => {
panic!("Failed to add blob: {:?}", e)
}
}
}))
Expand All @@ -281,11 +282,30 @@ impl IrohInstance {
})
.collect();

Ok(self
.blobs
Ok(blobs
.client()
.create_collection(collection, SetTagOption::Auto, Default::default())
.await
.expect("Failed to create collection."))
}
}

#[cfg(test)]
mod tests {
use crate::IrohInstance;

#[tokio::test]
async fn test_send_files() {
tracing_subscriber::fmt::init();
let cwd = std::env::current_dir().unwrap();

let files = vec![
cwd.join("Cargo.toml").to_string_lossy().to_string(),
cwd.join("Cargo.lock").to_string_lossy().to_string(),
];

let ticket = IrohInstance::send_files(files).await.unwrap();

println!("Ticket: {:?}", ticket);
}
}
16 changes: 4 additions & 12 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use tauri::{generate_context, generate_handler, AppHandle, Emitter, Manager};
use tokio::sync::mpsc;
use tokio::sync::Mutex;
struct AppState {
pub iroh: IrohInstance,
inner: Mutex<mpsc::Sender<Event>>,
}

Expand All @@ -22,9 +21,8 @@ enum Event {
}

impl AppState {
fn new(iroh: IrohInstance, async_proc_input_tx: mpsc::Sender<Event>) -> Self {
fn new(async_proc_input_tx: mpsc::Sender<Event>) -> Self {
AppState {
iroh,
inner: Mutex::new(async_proc_input_tx),
}
}
Expand All @@ -34,9 +32,7 @@ async fn setup<R: tauri::Runtime>(
handle: &tauri::AppHandle<R>,
async_proc_input_tx: mpsc::Sender<Event>,
) -> Result<()> {
let iroh = IrohInstance::new().await.map_err(|e| anyhow!(e))?;

handle.manage(AppState::new(iroh, async_proc_input_tx));
handle.manage(AppState::new(async_proc_input_tx));

Ok(())
}
Expand Down Expand Up @@ -112,9 +108,7 @@ async fn generate_ticket(
state: tauri::State<'_, AppState>,
paths: Vec<String>,
) -> Result<BlobTicket, InvokeError> {
state
.iroh
.send_files(paths)
IrohInstance::send_files(paths)
.await
.map_err(|e| InvokeError::from_anyhow(anyhow!(e)))
}
Expand All @@ -141,9 +135,7 @@ async fn receive_files(
}
}));

let files = state
.iroh
.receive_files(ticket)
let files = IrohInstance::receive_files(ticket)
.await
.map_err(|e| InvokeError::from_anyhow(anyhow!(e)))?;

Expand Down

0 comments on commit 99dceae

Please sign in to comment.