1pub use libqaul_types::*;
12pub use qrpc_sdk::{
13 default_socket_path,
14 error::{RpcError, RpcResult},
15 io::Message,
16 RpcSocket, Service,
17};
18pub use std::{str, sync::Arc};
19
20use rpc::{Capabilities, Reply, UserCapabilities, UserReply, ADDRESS};
21use users::UserAuth;
22
23pub struct QaulRpc {
31 socket: Arc<RpcSocket>,
32 addr: String,
33}
34
35impl QaulRpc {
36 pub fn connect(service: &Service) -> RpcResult<Self> {
37 let socket = service.get_socket();
38 let addr = service.name.clone();
39 Ok(Self { socket, addr })
40 }
41
42 pub fn users<'q>(&'q self) -> UserRpc<'q> {
43 UserRpc { rpc: self }
44 }
45
46 async fn send(&self, cap: Capabilities) -> RpcResult<Reply> {
47 let json = cap.to_json();
48 let msg = Message::to_addr(ADDRESS, &self.addr, json.as_bytes().to_vec());
49
50 self.socket
51 .send(msg, |Message { data, .. }| {
52 match str::from_utf8(data.as_slice())
53 .ok()
54 .and_then(|json| Reply::from_json(json))
55 {
56 Some(Reply::Error(e)) => Err(RpcError::Other(e.to_string())),
58 None => Err(RpcError::EncoderFault("Invalid json payload!".into())),
59 Some(r) => Ok(r),
60 }
61 })
62 .await
63 }
64}
65
66pub struct UserRpc<'q> {
67 rpc: &'q QaulRpc,
68}
69
70impl<'q> UserRpc<'q> {
71 pub async fn create<S: Into<String>>(&'q self, pw: S) -> RpcResult<UserAuth> {
72 if let Reply::Users(UserReply::Auth(auth)) = self
73 .rpc
74 .send(Capabilities::Users(UserCapabilities::Create {
75 pw: pw.into(),
76 }))
77 .await?
78 {
79 Ok(auth)
80 } else {
81 Err(RpcError::EncoderFault("Invalid reply payload!".into()))
82 }
83 }
84}