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, Inspect)]
39pub struct VmgsClient {
40 #[inspect(flatten, send = "VmgsBrokerRpc::Inspect")]
41 pub(crate) control: mesh_channel::Sender<VmgsBrokerRpc>,
42}
43
44impl VmgsClient {
45 #[instrument(skip_all, fields(file_id))]
47 pub async fn get_file_info(&self, file_id: FileId) -> Result<VmgsFileInfo, VmgsClientError> {
48 let res = self
49 .control
50 .call_failable(VmgsBrokerRpc::GetFileInfo, file_id)
51 .await?;
52
53 Ok(res)
54 }
55
56 #[instrument(skip_all, fields(file_id))]
58 pub async fn read_file(&self, file_id: FileId) -> Result<Vec<u8>, VmgsClientError> {
59 let res = self
60 .control
61 .call_failable(VmgsBrokerRpc::ReadFile, file_id)
62 .await?;
63
64 Ok(res)
65 }
66
67 #[instrument(skip_all, fields(file_id))]
72 pub async fn write_file(&self, file_id: FileId, buf: Vec<u8>) -> Result<(), VmgsClientError> {
73 self.control
74 .call_failable(VmgsBrokerRpc::WriteFile, (file_id, buf))
75 .await?;
76
77 Ok(())
78 }
79
80 #[cfg(with_encryption)]
84 #[instrument(skip_all, fields(file_id))]
85 pub async fn write_file_encrypted(
86 &self,
87 file_id: FileId,
88 buf: Vec<u8>,
89 ) -> Result<(), VmgsClientError> {
90 self.control
91 .call_failable(VmgsBrokerRpc::WriteFileEncrypted, (file_id, buf))
92 .await?;
93
94 Ok(())
95 }
96
97 pub async fn save(&self) -> Result<vmgs::save_restore::state::SavedVmgsState, VmgsClientError> {
103 let res = self.control.call(VmgsBrokerRpc::Save, ()).await?;
104 Ok(res)
105 }
106}