1use clap::Args;
24use log::debug;
25use nuts_backend::{Backend, Binary, Create, IdSize, Open, ReceiveHeader, HEADER_MAX_SIZE};
26use std::collections::HashMap;
27use std::convert::TryInto;
28use std::marker::PhantomData;
29use std::str::FromStr;
30use std::{cmp, io};
31
32use crate::bson::{BsonError, BsonReader, BsonWriter};
33use crate::msg::{ErrorResponse, Request, Response};
34use crate::plugin::cli::{CreateArgs, Format, InfoArgs, OpenArgs, PluginCommand};
35use crate::PluginInfo;
36
37fn into_header_bytes(bytes: &[u8]) -> Result<[u8; HEADER_MAX_SIZE], ErrorResponse> {
38 match bytes.try_into() {
39 Ok(header) => Ok(header),
40 Err(_err) => Err(ErrorResponse::InvalidHeaderBytes),
41 }
42}
43
44pub trait PluginHandler<B: Backend> {
53 type CreateArgs: Args;
55
56 type Create: Create<B>;
58
59 type Open: Open<B>;
61
62 fn plugin_info(&self) -> PluginInfo;
64
65 fn info_to_hash(&self, info: B::Info) -> Option<HashMap<String, String>>;
73
74 fn open_builder(&self, args: &OpenArgs) -> Option<Self::Open>;
77
78 fn create_builder(&self, args: &CreateArgs<Self::CreateArgs>) -> Option<Self::Create>;
80
81 fn handle_plugin_info(&self) -> Result<HashMap<String, String>, ErrorResponse> {
83 let info = self.plugin_info();
84
85 Ok([
86 ("name".to_string(), info.name().to_string()),
87 ("version".to_string(), info.version().to_string()),
88 ("revision".to_string(), info.revision().to_string()),
89 ]
90 .into())
91 }
92
93 fn handle_settings(
95 &self,
96 args: &CreateArgs<Self::CreateArgs>,
97 ) -> Result<Vec<u8>, ErrorResponse> {
98 match self.create_builder(args) {
99 Some(builder) => {
100 let settings = builder.settings();
101
102 Ok(<B::Settings as Binary>::as_bytes(&settings))
103 }
104 None => Err(ErrorResponse::message("unable to make a create-builder")),
105 }
106 }
107
108 fn handle_open(&self, args: &OpenArgs, settings: &[u8]) -> Result<B, ErrorResponse> {
110 let settings = <B::Settings as Binary>::from_bytes(settings)
111 .ok_or(ErrorResponse::InvalidSettingsData)?;
112
113 match self.open_builder(args) {
114 Some(builder) => builder
115 .build(settings)
116 .map_err(|err| ErrorResponse::backend::<B>(err)),
117 None => Err(ErrorResponse::message("unable to make an open-builder")),
118 }
119 }
120
121 fn handle_create(
123 &self,
124 args: &CreateArgs<Self::CreateArgs>,
125 header: &[u8],
126 overwrite: bool,
127 ) -> Result<B, ErrorResponse> {
128 let header = into_header_bytes(header)?;
129
130 match self.create_builder(args) {
131 Some(builder) => builder
132 .build(header, overwrite)
133 .map_err(|err| ErrorResponse::backend::<B>(err)),
134 None => Err(ErrorResponse::message("unable to make a create-builder")),
135 }
136 }
137
138 fn handle_id_size(&self) -> Result<usize, ErrorResponse> {
140 Ok(<B::Id as IdSize>::size())
141 }
142
143 fn handle_block_size(&self, backend: &B) -> Result<u32, ErrorResponse> {
145 Ok(B::block_size(backend))
146 }
147
148 fn handle_id_to_bytes(&self, str: &str) -> Result<Vec<u8>, ErrorResponse> {
150 let id = <B::Id as FromStr>::from_str(str).map_err(|_| ErrorResponse::InvalidId)?;
151
152 Ok(<B::Id as Binary>::as_bytes(&id))
153 }
154
155 fn handle_id_to_string(&self, bytes: &[u8]) -> Result<String, ErrorResponse> {
157 let id = <B::Id as Binary>::from_bytes(bytes).ok_or(ErrorResponse::InvalidIdData)?;
158
159 Ok(id.to_string())
160 }
161
162 fn handle_info(&self, backend: &B) -> Result<HashMap<String, String>, ErrorResponse> {
164 match backend.info() {
165 Ok(info) => Ok(self.info_to_hash(info).ok_or(ErrorResponse::InvalidInfo)?),
166 Err(err) => Err(ErrorResponse::backend::<B>(err)),
167 }
168 }
169
170 fn handle_aquire(&self, backend: &mut B, bytes: &[u8]) -> Result<Vec<u8>, ErrorResponse> {
172 match B::aquire(backend, bytes) {
173 Ok(id) => Ok(<B::Id as Binary>::as_bytes(&id)),
174 Err(err) => Err(ErrorResponse::backend::<B>(err)),
175 }
176 }
177
178 fn handle_release(&self, backend: &mut B, id: &[u8]) -> Result<(), ErrorResponse> {
180 let id = <B::Id as Binary>::from_bytes(id).ok_or(ErrorResponse::InvalidIdData)?;
181
182 B::release(backend, id).map_err(|err| ErrorResponse::backend::<B>(err))
183 }
184
185 fn handle_read_header<T: ReceiveHeader<B>>(
187 &self,
188 header: &mut T,
189 ) -> Result<Vec<u8>, ErrorResponse> {
190 let mut bytes = [0; HEADER_MAX_SIZE];
191
192 match header.get_header_bytes(&mut bytes) {
193 Ok(()) => Ok(bytes.to_vec()),
194 Err(err) => Err(ErrorResponse::backend::<B>(err)),
195 }
196 }
197
198 fn handle_write_header(&self, backend: &mut B, header: &[u8]) -> Result<(), ErrorResponse> {
200 let header = into_header_bytes(header)?;
201
202 B::write_header(backend, &header).map_err(|err| ErrorResponse::backend::<B>(err))
203 }
204
205 fn handle_read(&self, backend: &mut B, id: &[u8]) -> Result<Vec<u8>, ErrorResponse> {
207 let id = <B::Id as Binary>::from_bytes(id).ok_or(ErrorResponse::InvalidIdData)?;
208 let bsize = B::block_size(backend) as usize;
209 let mut buf = vec![0; bsize];
210
211 let nread =
212 B::read(backend, &id, &mut buf).map_err(|err| ErrorResponse::backend::<B>(err))?;
213
214 Ok(buf[..nread].to_vec())
215 }
216
217 fn handle_write(
219 &self,
220 backend: &mut B,
221 id: &[u8],
222 bytes: &[u8],
223 ) -> Result<usize, ErrorResponse> {
224 let id = <B::Id as Binary>::from_bytes(id).ok_or(ErrorResponse::InvalidIdData)?;
225
226 let bsize = B::block_size(backend) as usize;
227 let nbytes = cmp::min(bytes.len(), bsize);
228 let bytes = &bytes[..nbytes];
229
230 B::write(backend, &id, bytes).map_err(|err| ErrorResponse::backend::<B>(err))
231 }
232
233 fn handle_delete(&self, backend: B) -> Result<(), ErrorResponse> {
234 B::delete(backend);
235 Ok(())
236 }
237
238 fn handle_quit(&self) -> Result<(), ErrorResponse> {
239 Ok(())
240 }
241}
242
243pub struct InfoHandler<B, T> {
245 handler: T,
246 _data: PhantomData<B>,
247}
248
249impl<B: Backend, T: PluginHandler<B>> InfoHandler<B, T> {
250 pub fn new(handler: T) -> InfoHandler<B, T> {
253 InfoHandler {
254 handler,
255 _data: PhantomData,
256 }
257 }
258
259 pub fn run(&self, args: &InfoArgs) -> Result<(), BsonError> {
263 let info = self.handler.plugin_info();
264
265 match args.format {
266 Format::Text => {
267 println!("name: {}", info.name());
268 println!("version: {}", info.version());
269 println!("revision: {}", info.revision());
270 }
271 Format::Bson => {
272 BsonWriter::new(io::stdout()).write(info)?;
273 }
274 };
275
276 Ok(())
277 }
278}
279
280pub struct OpenCreateHandler<'a, B: Backend, T: PluginHandler<B>> {
282 command: &'a PluginCommand<T::CreateArgs>,
283 handler: T,
284 backend: Option<B>,
285}
286
287impl<'a, B: Backend, T: PluginHandler<B>> OpenCreateHandler<'a, B, T> {
288 pub fn new(
292 command: &'a PluginCommand<T::CreateArgs>,
293 handler: T,
294 ) -> OpenCreateHandler<'a, B, T> {
295 OpenCreateHandler {
296 command,
297 handler,
298 backend: None,
299 }
300 }
301
302 pub fn run(&mut self) -> Result<(), BsonError> {
304 let mut reader = BsonReader::new(io::stdin());
305 let mut writer = BsonWriter::new(io::stdout());
306
307 let mut leave_loop = false;
308
309 while !leave_loop {
310 match reader.read::<Request>() {
311 Ok(Some(request)) => {
312 debug!("request: {:?}", request);
313
314 let response = match request {
315 Request::PluginInfo => self.on_plugin_info(),
316 Request::Settings => self.on_settings(),
317 Request::Open(ref settings) => self.on_open(settings),
318 Request::Create(ref header, overwrite) => self.on_create(header, overwrite),
319 Request::IdSize => self.on_id_size(),
320 Request::BlockSize => self.on_block_size(),
321 Request::IdToBytes(ref str) => self.on_id_to_bytes(str),
322 Request::IdToString(ref bytes) => self.on_id_to_string(bytes),
323 Request::Info => self.on_info(),
324 Request::Aquire(ref bytes) => self.on_aquire(bytes),
325 Request::Release(ref id) => self.on_release(id),
326 Request::ReadHeader => self.on_read_header(),
327 Request::WriteHeader(ref header) => self.on_write_header(header),
328 Request::Read(ref id) => self.on_read(id),
329 Request::Write(ref id, ref bytes) => self.on_write(id, bytes),
330 Request::Delete => self.on_delete(),
331 Request::Quit => self.on_quit(),
332 };
333
334 leave_loop = request.as_quit().is_some() || response.as_error().is_some();
335 debug!("response: {:?}, leave: {}", response, leave_loop);
336
337 writer.write(response)?;
338 }
339 Ok(None) => {
340 leave_loop = true;
341 }
342 Err(err) => return Err(err),
343 }
344 }
345
346 Ok(())
347 }
348
349 fn on_plugin_info(&mut self) -> Response {
350 match self.handler.handle_plugin_info() {
351 Ok(info) => Response::ok_map(info),
352 Err(err) => Response::Err(err),
353 }
354 }
355
356 fn on_settings(&mut self) -> Response {
357 if let Some(args) = self.command.as_create() {
358 match self.handler.handle_settings(args) {
359 Ok(settings) => Response::ok_bytes(settings),
360 Err(err) => Response::Err(err),
361 }
362 } else {
363 Response::err_not_applicable()
364 }
365 }
366
367 fn on_open(&mut self, settings: &[u8]) -> Response {
368 if let Some(args) = self.command.as_open() {
369 match self.handler.handle_open(args, settings) {
370 Ok(backend) => {
371 self.backend = Some(backend);
372 Response::ok_void()
373 }
374 Err(err) => Response::Err(err),
375 }
376 } else {
377 Response::err_not_applicable()
378 }
379 }
380
381 fn on_create(&mut self, header: &[u8], overwrite: bool) -> Response {
382 if let Some(args) = self.command.as_create() {
383 match self.handler.handle_create(args, header, overwrite) {
384 Ok(backend) => {
385 self.backend = Some(backend);
386 Response::ok_void()
387 }
388 Err(err) => Response::Err(err),
389 }
390 } else {
391 Response::err_not_applicable()
392 }
393 }
394
395 fn on_id_size(&mut self) -> Response {
396 match self.handler.handle_id_size() {
397 Ok(size) => Response::ok_usize(size),
398 Err(err) => Response::Err(err),
399 }
400 }
401
402 fn on_block_size(&mut self) -> Response {
403 if let Some(backend) = self.backend.as_ref() {
404 match self.handler.handle_block_size(backend) {
405 Ok(size) => Response::ok_u32(size),
406 Err(err) => Response::Err(err),
407 }
408 } else {
409 Response::err_not_applicable()
410 }
411 }
412
413 fn on_id_to_bytes(&mut self, str: &str) -> Response {
414 match self.handler.handle_id_to_bytes(str) {
415 Ok(bytes) => Response::ok_bytes(bytes),
416 Err(err) => Response::Err(err),
417 }
418 }
419
420 fn on_id_to_string(&mut self, bytes: &[u8]) -> Response {
421 match self.handler.handle_id_to_string(bytes) {
422 Ok(str) => Response::ok_string(str),
423 Err(err) => Response::Err(err),
424 }
425 }
426
427 fn on_info(&mut self) -> Response {
428 if let Some(backend) = self.backend.as_ref() {
429 match self.handler.handle_info(backend) {
430 Ok(info) => Response::ok_map(info),
431 Err(err) => Response::Err(err),
432 }
433 } else {
434 Response::err_not_applicable()
435 }
436 }
437
438 fn on_aquire(&mut self, bytes: &[u8]) -> Response {
439 if let Some(backend) = self.backend.as_mut() {
440 match self.handler.handle_aquire(backend, bytes) {
441 Ok(id) => Response::ok_bytes(id),
442 Err(err) => Response::Err(err),
443 }
444 } else {
445 Response::err_not_applicable()
446 }
447 }
448
449 fn on_release(&mut self, id: &[u8]) -> Response {
450 if let Some(backend) = self.backend.as_mut() {
451 match self.handler.handle_release(backend, id) {
452 Ok(()) => Response::ok_void(),
453 Err(err) => Response::Err(err),
454 }
455 } else {
456 Response::err_not_applicable()
457 }
458 }
459
460 fn on_read_header(&mut self) -> Response {
461 if let Some(args) = self.command.as_open() {
462 if let Some(mut builder) = self.handler.open_builder(args) {
463 match self.handler.handle_read_header(&mut builder) {
464 Ok(header) => Response::ok_bytes(header),
465 Err(err) => Response::Err(err),
466 }
467 } else {
468 Response::err_message("unable to build an open-builder")
469 }
470 } else if let Some(backend) = self.backend.as_mut() {
471 match self.handler.handle_read_header(backend) {
472 Ok(header) => Response::ok_bytes(header),
473 Err(err) => Response::Err(err),
474 }
475 } else {
476 Response::err_not_applicable()
477 }
478 }
479
480 fn on_write_header(&mut self, header: &[u8]) -> Response {
481 if let Some(backend) = self.backend.as_mut() {
482 match self.handler.handle_write_header(backend, header) {
483 Ok(()) => Response::ok_void(),
484 Err(err) => Response::Err(err),
485 }
486 } else {
487 Response::err_not_applicable()
488 }
489 }
490
491 fn on_read(&mut self, id: &[u8]) -> Response {
492 if let Some(backend) = self.backend.as_mut() {
493 match self.handler.handle_read(backend, id) {
494 Ok(data) => Response::ok_bytes(data),
495 Err(err) => Response::Err(err),
496 }
497 } else {
498 Response::err_not_applicable()
499 }
500 }
501
502 fn on_write(&mut self, id: &[u8], bytes: &[u8]) -> Response {
503 if let Some(backend) = self.backend.as_mut() {
504 match self.handler.handle_write(backend, id, bytes) {
505 Ok(n) => Response::ok_usize(n),
506 Err(err) => Response::Err(err),
507 }
508 } else {
509 Response::err_not_applicable()
510 }
511 }
512
513 fn on_delete(&mut self) -> Response {
514 if let Some(backend) = self.backend.take() {
515 match self.handler.handle_delete(backend) {
516 Ok(()) => Response::ok_void(),
517 Err(err) => Response::Err(err),
518 }
519 } else {
520 Response::err_not_applicable()
521 }
522 }
523
524 fn on_quit(&self) -> Response {
525 match self.handler.handle_quit() {
526 Ok(()) => Response::ok_void(),
527 Err(err) => Response::Err(err),
528 }
529 }
530}