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