1use super::pb::v3lockpb;
4use crate::auth::AuthService;
5use crate::error::Result;
6use crate::intercept::InterceptedChannel;
7use crate::rpc::ResponseHeader;
8use http::HeaderValue;
9use std::sync::{Arc, RwLock};
10use tonic::{IntoRequest, Request};
11use v3lockpb::lock_client::LockClient as PbLockClient;
12use v3lockpb::{
13 LockRequest as PbLockRequest, LockResponse as PbLockResponse, UnlockRequest as PbUnlockRequest,
14 UnlockResponse as PbUnlockResponse,
15};
16
17#[repr(transparent)]
19#[derive(Clone)]
20pub struct LockClient {
21 inner: PbLockClient<AuthService<InterceptedChannel>>,
22}
23
24impl LockClient {
25 #[inline]
27 pub(crate) fn new(
28 channel: InterceptedChannel,
29 auth_token: Arc<RwLock<Option<HeaderValue>>>,
30 ) -> Self {
31 let inner = PbLockClient::new(AuthService::new(channel, auth_token));
32 Self { inner }
33 }
34
35 #[inline]
42 pub async fn lock(
43 &mut self,
44 name: impl Into<Vec<u8>>,
45 options: Option<LockOptions>,
46 ) -> Result<LockResponse> {
47 let resp = self
48 .inner
49 .lock(options.unwrap_or_default().with_name(name))
50 .await?
51 .into_inner();
52 Ok(LockResponse::new(resp))
53 }
54
55 #[inline]
59 pub async fn unlock(&mut self, key: impl Into<Vec<u8>>) -> Result<UnlockResponse> {
60 let resp = self
61 .inner
62 .unlock(UnlockOptions::new().with_key(key))
63 .await?
64 .into_inner();
65 Ok(UnlockResponse::new(resp))
66 }
67}
68
69#[derive(Debug, Default, Clone)]
71#[repr(transparent)]
72pub struct LockOptions(PbLockRequest);
73
74impl LockOptions {
75 #[inline]
77 fn with_name(mut self, name: impl Into<Vec<u8>>) -> Self {
78 self.0.name = name.into();
79 self
80 }
81
82 #[inline]
84 pub const fn new() -> Self {
85 Self(PbLockRequest {
86 name: Vec::new(),
87 lease: 0,
88 })
89 }
90
91 #[inline]
97 pub const fn with_lease(mut self, lease: i64) -> Self {
98 self.0.lease = lease;
99 self
100 }
101}
102
103impl From<LockOptions> for PbLockRequest {
104 #[inline]
105 fn from(options: LockOptions) -> Self {
106 options.0
107 }
108}
109
110impl IntoRequest<PbLockRequest> for LockOptions {
111 #[inline]
112 fn into_request(self) -> Request<PbLockRequest> {
113 Request::new(self.into())
114 }
115}
116
117#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
119#[derive(Debug, Default, Clone)]
120#[repr(transparent)]
121pub struct LockResponse(PbLockResponse);
122
123impl LockResponse {
124 #[inline]
126 const fn new(resp: PbLockResponse) -> Self {
127 Self(resp)
128 }
129
130 #[inline]
132 pub fn header(&self) -> Option<&ResponseHeader> {
133 self.0.header.as_ref().map(From::from)
134 }
135
136 #[inline]
138 pub fn take_header(&mut self) -> Option<ResponseHeader> {
139 self.0.header.take().map(ResponseHeader::new)
140 }
141
142 #[inline]
146 pub fn key(&self) -> &[u8] {
147 &self.0.key
148 }
149}
150
151#[derive(Debug, Default, Clone)]
153#[repr(transparent)]
154pub struct UnlockOptions(PbUnlockRequest);
155
156impl UnlockOptions {
157 #[inline]
159 fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
160 self.0.key = key.into();
161 self
162 }
163
164 #[inline]
166 pub const fn new() -> Self {
167 Self(PbUnlockRequest { key: Vec::new() })
168 }
169}
170
171impl From<UnlockOptions> for PbUnlockRequest {
172 #[inline]
173 fn from(options: UnlockOptions) -> Self {
174 options.0
175 }
176}
177
178impl IntoRequest<PbUnlockRequest> for UnlockOptions {
179 #[inline]
180 fn into_request(self) -> Request<PbUnlockRequest> {
181 Request::new(self.into())
182 }
183}
184
185#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
187#[derive(Debug, Default, Clone)]
188#[repr(transparent)]
189pub struct UnlockResponse(PbUnlockResponse);
190
191impl UnlockResponse {
192 #[inline]
194 const fn new(resp: PbUnlockResponse) -> Self {
195 Self(resp)
196 }
197
198 #[inline]
200 pub fn header(&self) -> Option<&ResponseHeader> {
201 self.0.header.as_ref().map(From::from)
202 }
203
204 #[inline]
206 pub fn take_header(&mut self) -> Option<ResponseHeader> {
207 self.0.header.take().map(ResponseHeader::new)
208 }
209}