xtask_todo_lib/devshell/workspace/
io.rs1use std::cell::RefCell;
6use std::rc::Rc;
7
8use crate::devshell::vfs::{Vfs, VfsError};
9#[cfg(any(unix, feature = "beta-vm"))]
10use crate::devshell::vm::GuestFsOps;
11use crate::devshell::vm::{GuestFsError, SessionHolder};
12
13#[cfg(unix)]
14use crate::devshell::vm::GammaSession;
15#[cfg(any(unix, feature = "beta-vm"))]
16use crate::devshell::workspace::logical_path_to_guest;
17use crate::devshell::workspace::WorkspaceBackendError;
18
19#[derive(Debug)]
21pub enum WorkspaceReadError {
22 Vfs(VfsError),
23 Guest(GuestFsError),
24 PathOutsideWorkspace,
25 Backend(WorkspaceBackendError),
26}
27
28impl std::fmt::Display for WorkspaceReadError {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Self::Vfs(e) => write!(f, "{e}"),
32 Self::Guest(e) => write!(f, "{e}"),
33 Self::PathOutsideWorkspace => f.write_str("path outside workspace"),
34 Self::Backend(e) => write!(f, "{e}"),
35 }
36 }
37}
38
39impl std::error::Error for WorkspaceReadError {
40 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41 match self {
42 Self::Vfs(e) => Some(e),
43 Self::Guest(e) => Some(e),
44 Self::Backend(e) => Some(e),
45 Self::PathOutsideWorkspace => None,
46 }
47 }
48}
49
50#[cfg(unix)]
52pub fn logical_to_guest_abs(
56 vfs: &Vfs,
57 g: &GammaSession,
58 logical_path: &str,
59) -> Result<String, WorkspaceBackendError> {
60 logical_path_to_guest(g.guest_mount(), vfs.cwd(), logical_path)
61}
62
63pub fn read_logical_file_bytes(
68 vfs: &mut Vfs,
69 vm_session: &mut SessionHolder,
70 path: &str,
71) -> Result<Vec<u8>, WorkspaceReadError> {
72 #[cfg(any(unix, feature = "beta-vm"))]
73 {
74 if let Some((ops, mount)) = vm_session.guest_primary_fs_ops_mut() {
75 let gp = match logical_path_to_guest(&mount, vfs.cwd(), path) {
76 Ok(p) => p,
77 Err(WorkspaceBackendError::PathOutsideWorkspace) => {
78 return Err(WorkspaceReadError::PathOutsideWorkspace);
79 }
80 Err(e) => return Err(WorkspaceReadError::Backend(e)),
81 };
82 return GuestFsOps::read_file(ops, &gp).map_err(WorkspaceReadError::Guest);
83 }
84 }
85 #[cfg(not(any(unix, feature = "beta-vm")))]
86 let _ = vm_session;
87 vfs.read_file(path).map_err(WorkspaceReadError::Vfs)
88}
89
90pub fn read_logical_file_bytes_rc(
95 vfs: &Rc<RefCell<Vfs>>,
96 vm_session: &Rc<RefCell<SessionHolder>>,
97 path: &str,
98) -> Result<Vec<u8>, WorkspaceReadError> {
99 read_logical_file_bytes(&mut vfs.borrow_mut(), &mut vm_session.borrow_mut(), path)
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105 use crate::devshell::vfs::Vfs;
106
107 #[test]
108 fn read_host_session_uses_vfs() {
109 let vfs = Rc::new(RefCell::new(Vfs::new()));
110 vfs.borrow_mut().mkdir("/a").unwrap();
111 vfs.borrow_mut().write_file("/a/x", b"hi").unwrap();
112 let vm = Rc::new(RefCell::new(SessionHolder::new_host()));
113 let got = read_logical_file_bytes_rc(&vfs, &vm, "/a/x").unwrap();
114 assert_eq!(got, b"hi");
115 }
116}