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}