diff --git a/desktop/src-tauri/src/commands.rs b/desktop/src-tauri/src/commands.rs index d020dad..c82e61e 100644 --- a/desktop/src-tauri/src/commands.rs +++ b/desktop/src-tauri/src/commands.rs @@ -122,25 +122,32 @@ pub fn enumerate(window: WebviewWindow) -> Result, } #[tauri::command] -pub fn open_device(bus_number: u8, address: u8) -> Result { - let device = if let Some(dev) = DEVICES.read().unwrap().get(&(bus_number, address)) { - if !matches!(dev.state, DeviceState::Closed) { - return Err("Already open".into()); +pub async fn open_device( + bus_number: u8, + address: u8, +) -> Result { + tauri::async_runtime::spawn_blocking(move || { + let device = if let Some(dev) = DEVICES.read().unwrap().get(&(bus_number, address)) { + if !matches!(dev.state, DeviceState::Closed) { + return Err("Already open".into()); + }; + dev.device.clone() + } else { + return Err("Failed to find device".into()); }; - dev.device.clone() - } else { - return Err("Failed to find device".into()); - }; - let handle = libnspire::Handle::new(device.open()?)?; - let info = handle.info()?; - { - let mut guard = DEVICES.write().unwrap(); - let device = guard - .get_mut(&(bus_number, address)) - .ok_or_else(|| anyhow::anyhow!("Device lost"))?; - device.state = DeviceState::Open(Arc::new(std::sync::Mutex::new(handle)), info.clone()); - } - Ok(info) + let handle = libnspire::Handle::new(device.open()?)?; + let info = handle.info()?; + { + let mut guard = DEVICES.write().unwrap(); + let device = guard + .get_mut(&(bus_number, address)) + .ok_or_else(|| anyhow::anyhow!("Device lost"))?; + device.state = DeviceState::Open(Arc::new(std::sync::Mutex::new(handle)), info.clone()); + } + Ok(info) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] @@ -154,221 +161,261 @@ pub fn close_device(bus_number: u8, address: u8) -> Result( +pub async fn update_device( bus_number: u8, address: u8, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - let info = err_wrap(handle.info(), dev, &window)?; - Ok(info) +) -> Result { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + let info = err_wrap(handle.info(), dev, &window)?; + Ok(info) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn list_dir( +pub async fn list_dir( bus_number: u8, address: u8, path: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - let dir = err_wrap(handle.list_dir(&path), dev, &window)?; +) -> Result, SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + let dir = err_wrap(handle.list_dir(&path), dev, &window)?; - Ok( - dir - .iter() - .map(|file| FileInfo { - path: file.name().to_string_lossy().to_string(), - is_dir: file.entry_type() == EntryType::Directory, - date: file.date(), - size: file.size(), - }) - .collect::>(), - ) + Ok( + dir + .iter() + .map(|file| FileInfo { + path: file.name().to_string_lossy().to_string(), + is_dir: file.entry_type() == EntryType::Directory, + date: file.date(), + size: file.size(), + }) + .collect::>(), + ) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn download_file( +pub async fn download_file( bus_number: u8, address: u8, path: (String, u64), dest: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let (file, size) = path; - let dest = PathBuf::from(dest); - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - let mut buf = vec![0; size as usize]; - err_wrap( - handle.read_file( - &file, - &mut buf, - &mut progress_sender(&window, dev, size as usize), - ), - dev, - &window, - )?; - if let Some(name) = file.split('/').last() { - File::create(dest.join(name))?.write_all(&buf)?; - } - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let (file, size) = path; + let dest = PathBuf::from(dest); + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + let mut buf = vec![0; size as usize]; + err_wrap( + handle.read_file( + &file, + &mut buf, + &mut progress_sender(&window, dev, size as usize), + ), + dev, + &window, + )?; + if let Some(name) = file.split('/').last() { + File::create(dest.join(name))?.write_all(&buf)?; + } + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn upload_file( +pub async fn upload_file( bus_number: u8, address: u8, path: String, src: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let file = PathBuf::from(src); - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - let mut buf = vec![]; - File::open(&file)?.read_to_end(&mut buf)?; - let name = file - .file_name() - .ok_or_else(|| anyhow::anyhow!("Failed to get file name"))? - .to_string_lossy() - .to_string(); - err_wrap( - handle.write_file( - &format!("{}/{}", path, name), - &buf, - &mut progress_sender(&window, dev, buf.len()), - ), - dev, - &window, - )?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let file = PathBuf::from(src); + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + let mut buf = vec![]; + File::open(&file)?.read_to_end(&mut buf)?; + let name = file + .file_name() + .ok_or_else(|| anyhow::anyhow!("Failed to get file name"))? + .to_string_lossy() + .to_string(); + err_wrap( + handle.write_file( + &format!("{}/{}", path, name), + &buf, + &mut progress_sender(&window, dev, buf.len()), + ), + dev, + &window, + )?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn upload_os( +pub async fn upload_os( bus_number: u8, address: u8, src: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - let mut buf = vec![]; - File::open(&src)?.read_to_end(&mut buf)?; - err_wrap( - handle.send_os(&buf, &mut progress_sender(&window, dev, buf.len())), - dev, - &window, - )?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + let mut buf = vec![]; + File::open(&src)?.read_to_end(&mut buf)?; + err_wrap( + handle.send_os(&buf, &mut progress_sender(&window, dev, buf.len())), + dev, + &window, + )?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn delete_file( +pub async fn delete_file( bus_number: u8, address: u8, path: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - err_wrap(handle.delete_file(&path), dev, &window)?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + err_wrap(handle.delete_file(&path), dev, &window)?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn delete_dir( +pub async fn delete_dir( bus_number: u8, address: u8, path: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - err_wrap(handle.delete_dir(&path), dev, &window)?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + err_wrap(handle.delete_dir(&path), dev, &window)?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn create_nspire_dir( +pub async fn create_nspire_dir( bus_number: u8, address: u8, path: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - err_wrap(handle.create_dir(&path), dev, &window)?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + err_wrap(handle.create_dir(&path), dev, &window)?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn move_file( +pub async fn move_file( bus_number: u8, address: u8, src: String, dest: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - err_wrap(handle.move_file(&src, &dest), dev, &window)?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + err_wrap(handle.move_file(&src, &dest), dev, &window)?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? } #[tauri::command] -pub fn copy( +pub async fn copy( bus_number: u8, address: u8, src: String, dest: String, window: WebviewWindow, -) -> Result { - let dev = DevId { - bus_number, - address, - }; - let handle = get_open_dev(&dev)?; - let handle = handle.lock().unwrap(); - err_wrap(handle.copy_file(&src, &dest), dev, &window)?; - Ok(()) +) -> Result<(), SerializedError> { + tauri::async_runtime::spawn_blocking(move || { + let dev = DevId { + bus_number, + address, + }; + let handle = get_open_dev(&dev)?; + let handle = handle.lock().unwrap(); + err_wrap(handle.copy_file(&src, &dest), dev, &window)?; + Ok(()) + }) + .await + .map_err(|e| SerializedError::from(e))? }