nuts_tool_api/plugin/runner.rs
1// MIT License
2//
3// Copyright (c) 2024 Robin Doer
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to
7// deal in the Software without restriction, including without limitation the
8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9// sell copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21// IN THE SOFTWARE.
22
23use clap::Parser;
24use env_logger::Builder;
25use log::{Level, LevelFilter};
26use nuts_backend::Backend;
27use std::io::Write;
28
29use crate::bson::BsonError;
30use crate::plugin::cli::{PluginCli, PluginCommand};
31use crate::plugin::handler::{InfoHandler, OpenCreateHandler, PluginHandler};
32
33/// Runs the plugin.
34///
35/// The `PluginRunner` utility brings [`PluginHandler`] and
36/// [cli](crate::plugin::cli) together and starts the plugin process.
37///
38/// You need to configure the [logging](`Self::configure_logging`) and finally
39/// call [`Self::run`] to start the process.
40pub struct PluginRunner<B: Backend, T: PluginHandler<B>> {
41 cli: PluginCli<T::CreateArgs>,
42 handler: T,
43}
44
45impl<B: Backend, T: PluginHandler<B>> PluginRunner<B, T> {
46 /// Creates a new `PluginRunner` instance.
47 ///
48 /// The given [`PluginHandler`] is attached to the runner.
49 pub fn new(handler: T) -> PluginRunner<B, T> {
50 PluginRunner {
51 cli: PluginCli::parse(),
52 handler,
53 }
54 }
55
56 /// Configures logging for the plugin process. You need to call this method
57 /// before [`Self::run()`] in order to have some logging.
58 pub fn configure_logging(&mut self) -> &mut Self {
59 let mut builder = Builder::new();
60
61 builder.filter_level(match self.cli.verbose {
62 0 => LevelFilter::Off,
63 1 => LevelFilter::Info,
64 2 => LevelFilter::Debug,
65 _ => LevelFilter::Trace,
66 });
67 builder.format(|buf, record| {
68 let prefix = match record.metadata().level() {
69 Level::Error => "nuts-log-error",
70 Level::Warn => "nuts-log-warn",
71 Level::Info => "nuts-log-info",
72 Level::Debug => "nuts-log-debug",
73 Level::Trace => "nuts-log-trace",
74 };
75
76 writeln!(buf, "{}: {}", prefix, record.args())
77 });
78 builder.init();
79
80 self
81 }
82
83 /// Runs the plugin process.
84 pub fn run(self) -> Result<(), BsonError> {
85 match self.cli.command {
86 PluginCommand::Info(args) => InfoHandler::new(self.handler).run(&args),
87 _ => OpenCreateHandler::new(&self.cli.command, self.handler).run(),
88 }
89 }
90}