1use super::pb::v3lockpb;
4use crate::error::Result;
5use crate::intercept::InterceptedChannel;
6use crate::rpc::ResponseHeader;
7use tonic::{IntoRequest, Request};
8use v3lockpb::lock_client::LockClient as PbLockClient;
9use v3lockpb::{
10 LockRequest as PbLockRequest, LockResponse as PbLockResponse, UnlockRequest as PbUnlockRequest,
11 UnlockResponse as PbUnlockResponse,
12};
13
14#[repr(transparent)]
16#[derive(Clone)]
17pub struct LockClient {
18 inner: PbLockClient<InterceptedChannel>,
19}
20
21impl LockClient {
22 #[inline]
24 pub(crate) fn new(channel: InterceptedChannel) -> Self {
25 let inner = PbLockClient::new(channel);
26 Self { inner }
27 }
28
29 #[inline]
36 pub async fn lock(
37 &mut self,
38 name: impl Into<Vec<u8>>,
39 options: Option<LockOptions>,
40 ) -> Result<LockResponse> {
41 let resp = self
42 .inner
43 .lock(options.unwrap_or_default().with_name(name))
44 .await?
45 .into_inner();
46 Ok(LockResponse::new(resp))
47 }
48
49 #[inline]
53 pub async fn unlock(&mut self, key: impl Into<Vec<u8>>) -> Result<UnlockResponse> {
54 let resp = self
55 .inner
56 .unlock(UnlockOptions::new().with_key(key))
57 .await?
58 .into_inner();
59 Ok(UnlockResponse::new(resp))
60 }
61}
62
63#[derive(Debug, Default, Clone)]
65#[repr(transparent)]
66pub struct LockOptions(PbLockRequest);
67
68impl LockOptions {
69 #[inline]
71 fn with_name(mut self, name: impl Into<Vec<u8>>) -> Self {
72 self.0.name = name.into();
73 self
74 }
75
76 #[inline]
78 pub const fn new() -> Self {
79 Self(PbLockRequest {
80 name: Vec::new(),
81 lease: 0,
82 })
83 }
84
85 #[inline]
91 pub const fn with_lease(mut self, lease: i64) -> Self {
92 self.0.lease = lease;
93 self
94 }
95}
96
97impl From<LockOptions> for PbLockRequest {
98 #[inline]
99 fn from(options: LockOptions) -> Self {
100 options.0
101 }
102}
103
104impl IntoRequest<PbLockRequest> for LockOptions {
105 #[inline]
106 fn into_request(self) -> Request<PbLockRequest> {
107 Request::new(self.into())
108 }
109}
110
111#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
113#[derive(Debug, Default, Clone)]
114#[repr(transparent)]
115pub struct LockResponse(PbLockResponse);
116
117impl LockResponse {
118 #[inline]
120 const fn new(resp: PbLockResponse) -> Self {
121 Self(resp)
122 }
123
124 #[inline]
126 pub fn header(&self) -> Option<&ResponseHeader> {
127 self.0.header.as_ref().map(From::from)
128 }
129
130 #[inline]
132 pub fn take_header(&mut self) -> Option<ResponseHeader> {
133 self.0.header.take().map(ResponseHeader::new)
134 }
135
136 #[inline]
140 pub fn key(&self) -> &[u8] {
141 &self.0.key
142 }
143}
144
145#[derive(Debug, Default, Clone)]
147#[repr(transparent)]
148pub struct UnlockOptions(PbUnlockRequest);
149
150impl UnlockOptions {
151 #[inline]
153 fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
154 self.0.key = key.into();
155 self
156 }
157
158 #[inline]
160 pub const fn new() -> Self {
161 Self(PbUnlockRequest { key: Vec::new() })
162 }
163}
164
165impl From<UnlockOptions> for PbUnlockRequest {
166 #[inline]
167 fn from(options: UnlockOptions) -> Self {
168 options.0
169 }
170}
171
172impl IntoRequest<PbUnlockRequest> for UnlockOptions {
173 #[inline]
174 fn into_request(self) -> Request<PbUnlockRequest> {
175 Request::new(self.into())
176 }
177}
178
179#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
181#[derive(Debug, Default, Clone)]
182#[repr(transparent)]
183pub struct UnlockResponse(PbUnlockResponse);
184
185impl UnlockResponse {
186 #[inline]
188 const fn new(resp: PbUnlockResponse) -> Self {
189 Self(resp)
190 }
191
192 #[inline]
194 pub fn header(&self) -> Option<&ResponseHeader> {
195 self.0.header.as_ref().map(From::from)
196 }
197
198 #[inline]
200 pub fn take_header(&mut self) -> Option<ResponseHeader> {
201 self.0.header.take().map(ResponseHeader::new)
202 }
203}