1use super::pb::v3lockpb;
4use crate::auth::AuthService;
5use crate::channel::Channel;
6use crate::error::Result;
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<Channel>>,
22}
23
24impl LockClient {
25 #[inline]
27 pub(crate) fn new(channel: Channel, auth_token: Arc<RwLock<Option<HeaderValue>>>) -> Self {
28 let inner = PbLockClient::new(AuthService::new(channel, auth_token));
29 Self { inner }
30 }
31
32 #[inline]
39 pub async fn lock(
40 &mut self,
41 name: impl Into<Vec<u8>>,
42 options: Option<LockOptions>,
43 ) -> Result<LockResponse> {
44 let resp = self
45 .inner
46 .lock(options.unwrap_or_default().with_name(name))
47 .await?
48 .into_inner();
49 Ok(LockResponse::new(resp))
50 }
51
52 #[inline]
56 pub async fn unlock(&mut self, key: impl Into<Vec<u8>>) -> Result<UnlockResponse> {
57 let resp = self
58 .inner
59 .unlock(UnlockOptions::new().with_key(key))
60 .await?
61 .into_inner();
62 Ok(UnlockResponse::new(resp))
63 }
64}
65
66#[derive(Debug, Default, Clone)]
68#[repr(transparent)]
69pub struct LockOptions(PbLockRequest);
70
71impl LockOptions {
72 #[inline]
74 fn with_name(mut self, name: impl Into<Vec<u8>>) -> Self {
75 self.0.name = name.into();
76 self
77 }
78
79 #[inline]
81 pub const fn new() -> Self {
82 Self(PbLockRequest {
83 name: Vec::new(),
84 lease: 0,
85 })
86 }
87
88 #[inline]
94 pub const fn with_lease(mut self, lease: i64) -> Self {
95 self.0.lease = lease;
96 self
97 }
98}
99
100impl From<LockOptions> for PbLockRequest {
101 #[inline]
102 fn from(options: LockOptions) -> Self {
103 options.0
104 }
105}
106
107impl IntoRequest<PbLockRequest> for LockOptions {
108 #[inline]
109 fn into_request(self) -> Request<PbLockRequest> {
110 Request::new(self.into())
111 }
112}
113
114#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
116#[derive(Debug, Default, Clone)]
117#[repr(transparent)]
118pub struct LockResponse(PbLockResponse);
119
120impl LockResponse {
121 #[inline]
123 const fn new(resp: PbLockResponse) -> Self {
124 Self(resp)
125 }
126
127 #[inline]
129 pub fn header(&self) -> Option<&ResponseHeader> {
130 self.0.header.as_ref().map(From::from)
131 }
132
133 #[inline]
135 pub fn take_header(&mut self) -> Option<ResponseHeader> {
136 self.0.header.take().map(ResponseHeader::new)
137 }
138
139 #[inline]
143 pub fn key(&self) -> &[u8] {
144 &self.0.key
145 }
146}
147
148#[derive(Debug, Default, Clone)]
150#[repr(transparent)]
151pub struct UnlockOptions(PbUnlockRequest);
152
153impl UnlockOptions {
154 #[inline]
156 fn with_key(mut self, key: impl Into<Vec<u8>>) -> Self {
157 self.0.key = key.into();
158 self
159 }
160
161 #[inline]
163 pub const fn new() -> Self {
164 Self(PbUnlockRequest { key: Vec::new() })
165 }
166}
167
168impl From<UnlockOptions> for PbUnlockRequest {
169 #[inline]
170 fn from(options: UnlockOptions) -> Self {
171 options.0
172 }
173}
174
175impl IntoRequest<PbUnlockRequest> for UnlockOptions {
176 #[inline]
177 fn into_request(self) -> Request<PbUnlockRequest> {
178 Request::new(self.into())
179 }
180}
181
182#[cfg_attr(feature = "pub-response-field", visible::StructFields(pub))]
184#[derive(Debug, Default, Clone)]
185#[repr(transparent)]
186pub struct UnlockResponse(PbUnlockResponse);
187
188impl UnlockResponse {
189 #[inline]
191 const fn new(resp: PbUnlockResponse) -> Self {
192 Self(resp)
193 }
194
195 #[inline]
197 pub fn header(&self) -> Option<&ResponseHeader> {
198 self.0.header.as_ref().map(From::from)
199 }
200
201 #[inline]
203 pub fn take_header(&mut self) -> Option<ResponseHeader> {
204 self.0.header.take().map(ResponseHeader::new)
205 }
206}