1mod interface;
6
7use std::{cell::RefCell, io, ops::DerefMut};
8
9use crate::{
10 wire::{XsMessage, XsMessageType},
11 Xs,
12};
13
14pub struct XsUnix(RefCell<interface::XsUnixInterface>);
16
17impl XsUnix {
18 pub fn new() -> io::Result<Self> {
23 Ok(Self(RefCell::new(interface::XsUnixInterface::new()?)))
24 }
25
26 fn transmit_request(&self, request: XsMessage) -> io::Result<XsMessage> {
27 let mut writer = self.0.borrow_mut();
28 request.write_to(writer.deref_mut())?;
29
30 let response = XsMessage::read_from(writer.deref_mut())?;
31
32 match response.msg_type {
33 msg_type if msg_type == request.msg_type => Ok(response),
35 XsMessageType::Error => Err(response.parse_error()),
36 msg_type => Err(io::Error::new(
37 io::ErrorKind::InvalidData,
38 format!("Got unrelated response ({msg_type:?})"),
39 )),
40 }
41 }
42}
43
44impl Xs for XsUnix {
45 fn directory(&self, path: &str) -> io::Result<Vec<Box<str>>> {
46 let response =
49 self.transmit_request(XsMessage::from_string(XsMessageType::Directory, 0, path))?;
50
51 Ok(response
52 .parse_payload_list()
53 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?
54 .iter()
56 .map(|s| s.to_string().into_boxed_str())
57 .collect())
58 }
59
60 fn read(&self, path: &str) -> io::Result<Box<str>> {
61 let response =
62 self.transmit_request(XsMessage::from_string(XsMessageType::Read, 0, path))?;
63
64 Ok(response
65 .parse_payload_str()
66 .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?
67 .unwrap_or_default()
68 .to_string()
70 .into_boxed_str())
71 }
72
73 fn write(&self, path: &str, data: &str) -> io::Result<()> {
74 self.transmit_request(XsMessage::from_string_slice(
75 XsMessageType::Write,
76 0,
77 &[path, data],
78 false,
79 ))?;
80
81 Ok(())
82 }
83
84 fn rm(&self, path: &str) -> io::Result<()> {
85 self.transmit_request(XsMessage::from_string(XsMessageType::Rm, 0, path))?;
86
87 Ok(())
88 }
89}