1use crate::broker::VmgsBrokerRpc;
8use inspect::Inspect;
9use mesh_channel::rpc::RpcError;
10use mesh_channel::rpc::RpcSend;
11use thiserror::Error;
12use tracing::instrument;
13use vmgs::VmgsFileInfo;
14use vmgs_format::FileId;
15
16#[derive(Debug, Error)]
18#[non_exhaustive]
19pub enum VmgsClientError {
20 #[error("broker is offline")]
22 BrokerOffline(#[from] RpcError),
23 #[error("vmgs error")]
25 Vmgs(#[from] vmgs::Error),
26}
27
28impl From<RpcError<vmgs::Error>> for VmgsClientError {
29 fn from(value: RpcError<vmgs::Error>) -> Self {
30 match value {
31 RpcError::Call(e) => VmgsClientError::Vmgs(e),
32 RpcError::Channel(e) => VmgsClientError::BrokerOffline(RpcError::Channel(e)),
33 }
34 }
35}
36
37#[derive(Clone)]
39pub struct VmgsClient {
40 pub(crate) control: mesh_channel::Sender<VmgsBrokerRpc>,
41}
42
43impl Inspect for VmgsClient {
44 fn inspect(&self, req: inspect::Request<'_>) {
45 self.control.send(VmgsBrokerRpc::Inspect(req.defer()));
46 }
47}
48
49impl VmgsClient {
50 #[instrument(skip_all, fields(file_id))]
52 pub async fn get_file_info(&self, file_id: FileId) -> Result<VmgsFileInfo, VmgsClientError> {
53 let res = self
54 .control
55 .call_failable(VmgsBrokerRpc::GetFileInfo, file_id)
56 .await?;
57
58 Ok(res)
59 }
60
61 #[instrument(skip_all, fields(file_id))]
63 pub async fn read_file(&self, file_id: FileId) -> Result<Vec<u8>, VmgsClientError> {
64 let res = self
65 .control
66 .call_failable(VmgsBrokerRpc::ReadFile, file_id)
67 .await?;
68
69 Ok(res)
70 }
71
72 #[instrument(skip_all, fields(file_id))]
77 pub async fn write_file(&self, file_id: FileId, buf: Vec<u8>) -> Result<(), VmgsClientError> {
78 self.control
79 .call_failable(VmgsBrokerRpc::WriteFile, (file_id, buf))
80 .await?;
81
82 Ok(())
83 }
84
85 #[cfg(with_encryption)]
89 #[instrument(skip_all, fields(file_id))]
90 pub async fn write_file_encrypted(
91 &self,
92 file_id: FileId,
93 buf: Vec<u8>,
94 ) -> Result<(), VmgsClientError> {
95 self.control
96 .call_failable(VmgsBrokerRpc::WriteFileEncrypted, (file_id, buf))
97 .await?;
98
99 Ok(())
100 }
101
102 pub async fn save(&self) -> Result<vmgs::save_restore::state::SavedVmgsState, VmgsClientError> {
108 let res = self.control.call(VmgsBrokerRpc::Save, ()).await?;
109 Ok(res)
110 }
111}