Compare commits
4 Commits
main
...
feature/nu
Author | SHA1 | Date | |
---|---|---|---|
489965cdc9 | |||
c73ce95fd9 | |||
54adfe5095 | |||
bb85b2054c |
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -3505,6 +3505,16 @@ dependencies = [
|
||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nu_plugin_once"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nu-cmd-lang",
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-plugin-test-support",
|
||||||
|
"nu-protocol",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_polars"
|
name = "nu_plugin_polars"
|
||||||
version = "0.96.2"
|
version = "0.96.2"
|
||||||
|
|
|
@ -51,6 +51,7 @@ members = [
|
||||||
"crates/nu_plugin_query",
|
"crates/nu_plugin_query",
|
||||||
"crates/nu_plugin_custom_values",
|
"crates/nu_plugin_custom_values",
|
||||||
"crates/nu_plugin_formats",
|
"crates/nu_plugin_formats",
|
||||||
|
"crates/nu_plugin_once",
|
||||||
"crates/nu_plugin_polars",
|
"crates/nu_plugin_polars",
|
||||||
"crates/nu_plugin_stress_internals",
|
"crates/nu_plugin_stress_internals",
|
||||||
"crates/nu-std",
|
"crates/nu-std",
|
||||||
|
|
18
Cross.toml
18
Cross.toml
|
@ -1,18 +1,10 @@
|
||||||
# Configuration for cross-rs: https://github.com/cross-rs/cross
|
# Configuration for cross-rs: https://github.com/cross-rs/cross
|
||||||
# Run cross-rs like this:
|
# Run cross-rs like this:
|
||||||
# cross build --target aarch64-unknown-linux-gnu --release
|
# cross build --target i686-unknown-linux-musl --release --features=static-link-openssl
|
||||||
# or
|
|
||||||
# cross build --target aarch64-unknown-linux-musl --release --features=static-link-openssl
|
|
||||||
|
|
||||||
[target.aarch64-unknown-linux-gnu]
|
|
||||||
pre-build = [
|
|
||||||
"dpkg --add-architecture $CROSS_DEB_ARCH",
|
|
||||||
"apt-get update && apt-get install --assume-yes libssl-dev:$CROSS_DEB_ARCH clang"
|
|
||||||
]
|
|
||||||
|
|
||||||
# NOTE: for musl you will need to build with --features=static-link-openssl
|
# NOTE: for musl you will need to build with --features=static-link-openssl
|
||||||
[target.aarch64-unknown-linux-musl]
|
[target.i686-unknown-linux-musl]
|
||||||
pre-build = [
|
pre-build = [
|
||||||
"dpkg --add-architecture $CROSS_DEB_ARCH",
|
"dpkg --add-architecture i386",
|
||||||
"apt-get update && apt-get install --assume-yes clang"
|
"apt-get update && apt-get install --assume-yes libssl-dev:i386 clang"
|
||||||
]
|
]
|
23
crates/nu_plugin_once/Cargo.toml
Normal file
23
crates/nu_plugin_once/Cargo.toml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
authors = ["Chris Daßler"]
|
||||||
|
description = "A object oriented shell plugin for Nushell"
|
||||||
|
repository = "https://github.com/nushell/nushell/tree/main/crates/nu_plugin_example"
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT"
|
||||||
|
name = "nu_plugin_once"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "nu_plugin_once"
|
||||||
|
bench = false
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
bench = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nu-plugin = { path = "../nu-plugin", version = "0.96.1" }
|
||||||
|
nu-protocol = { path = "../nu-protocol", version = "0.96.1", features = ["plugin"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
nu-plugin-test-support = { path = "../nu-plugin-test-support", version = "0.96.1" }
|
||||||
|
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.96.1" }
|
36
crates/nu_plugin_once/README.md
Normal file
36
crates/nu_plugin_once/README.md
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Plugin Once
|
||||||
|
|
||||||
|
Crate with a simple example of the Plugin trait that needs to be implemented
|
||||||
|
in order to create a binary that can be registered into nushell declaration list
|
||||||
|
|
||||||
|
## `once config`
|
||||||
|
|
||||||
|
This subcommand demonstrates sending configuration from the nushell `$env.config` to a plugin.
|
||||||
|
|
||||||
|
To make use of the plugin after building `nushell` run:
|
||||||
|
|
||||||
|
```nushell
|
||||||
|
plugin add target/debug/nu_plugin_once
|
||||||
|
# or then either restart your current nushell session or run:
|
||||||
|
plugin use target/debug/nu_plugin_once
|
||||||
|
```
|
||||||
|
|
||||||
|
The configuration for the plugin lives in `$env.config.plugins.once`:
|
||||||
|
|
||||||
|
```nushell
|
||||||
|
$env.config = {
|
||||||
|
plugins: {
|
||||||
|
once: [
|
||||||
|
some
|
||||||
|
values
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To list plugin values run:
|
||||||
|
|
||||||
|
```nushell
|
||||||
|
once config
|
||||||
|
```
|
||||||
|
|
47
crates/nu_plugin_once/src/commands/main.rs
Normal file
47
crates/nu_plugin_once/src/commands/main.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_protocol::{Category, LabeledError, Signature, Value};
|
||||||
|
|
||||||
|
use crate::OncePlugin;
|
||||||
|
|
||||||
|
pub struct Main;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for Main {
|
||||||
|
type Plugin = OncePlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"once"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"once commands for Nushell plugins"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extra_usage(&self) -> &str {
|
||||||
|
r#"
|
||||||
|
The `once` plugin demonstrates usage of the Nushell plugin API.
|
||||||
|
|
||||||
|
Several commands provided to test and demonstrate different capabilities of
|
||||||
|
plugins exposed through the API. None of these commands are intended to be
|
||||||
|
particularly useful.
|
||||||
|
"#
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build(self.name()).category(Category::Experimental)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_terms(&self) -> Vec<&str> {
|
||||||
|
vec!["once"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
_plugin: &Self::Plugin,
|
||||||
|
engine: &EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::string(engine.get_help()?, call.head))
|
||||||
|
}
|
||||||
|
}
|
10
crates/nu_plugin_once/src/commands/mod.rs
Normal file
10
crates/nu_plugin_once/src/commands/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// `once` command - just suggests to call --help
|
||||||
|
mod main;
|
||||||
|
|
||||||
|
pub use main::Main;
|
||||||
|
|
||||||
|
mod scenario;
|
||||||
|
pub use scenario::Scenario;
|
||||||
|
|
||||||
|
mod scenario_deploy;
|
||||||
|
pub use scenario_deploy::ScenarioDeploy;
|
93
crates/nu_plugin_once/src/commands/scenario.rs
Normal file
93
crates/nu_plugin_once/src/commands/scenario.rs
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_protocol::{
|
||||||
|
record, Category, Example, IntoSpanned, LabeledError, PipelineData, Signature, Spanned, Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::OncePlugin;
|
||||||
|
|
||||||
|
pub struct Scenario;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for Scenario {
|
||||||
|
type Plugin = OncePlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"once scenario"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Manage once scenarios on local or remote servers."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extra_usage(&self) -> &str {
|
||||||
|
r"This command shows all available scenarios. To manage these scenarios use the sub commands, e.g.
|
||||||
|
|
||||||
|
> once scenario.deploy"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build(self.name()).category(Category::Experimental)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_terms(&self) -> Vec<&str> {
|
||||||
|
vec!["once", "scenario"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![Example {
|
||||||
|
example: "once scenario",
|
||||||
|
description: "List all scenarios",
|
||||||
|
result: Some(Value::test_list(vec![Value::test_record(record! {
|
||||||
|
"name" => Value::test_string("test"),
|
||||||
|
"filename" => Value::test_string("test.scenario.env")
|
||||||
|
})])),
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
_plugin: &OncePlugin,
|
||||||
|
engine: &EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
let head = call.head;
|
||||||
|
|
||||||
|
const SCENARIO_SOURCE_PATH: &str = "/workspaces/Once.2023/Scenarios";
|
||||||
|
let name: Spanned<String> = Spanned {
|
||||||
|
span: head,
|
||||||
|
item: "glob".to_owned(),
|
||||||
|
};
|
||||||
|
let decl_id = engine.find_decl(&name.item)?.ok_or_else(|| {
|
||||||
|
LabeledError::new(format!("Can't find `{}`", name.item))
|
||||||
|
.with_label("not in scope", name.span)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut new_call = EvaluatedCall::new(call.head);
|
||||||
|
//new_call.add_flag("l".into_spanned(head));
|
||||||
|
new_call.add_positional(Value::string(
|
||||||
|
format!("{}/**/*.{{scenario,env}}", SCENARIO_SOURCE_PATH),
|
||||||
|
head,
|
||||||
|
));
|
||||||
|
// TODO: Filter out localhost is not working yet
|
||||||
|
new_call.add_named(
|
||||||
|
"exclude".into_spanned(head),
|
||||||
|
Value::string("[**/localhost/*]", head),
|
||||||
|
);
|
||||||
|
|
||||||
|
let result: PipelineData =
|
||||||
|
engine.call_decl(decl_id, new_call, PipelineData::Empty, true, false)?;
|
||||||
|
|
||||||
|
let mut list = vec![];
|
||||||
|
for res in result.into_iter() {
|
||||||
|
list.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::list(list, head))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||||
|
use nu_plugin_test_support::PluginTest;
|
||||||
|
PluginTest::new("once", OncePlugin.into())?.test_command_examples(&Scenario)
|
||||||
|
}
|
162
crates/nu_plugin_once/src/commands/scenario_deploy.rs
Normal file
162
crates/nu_plugin_once/src/commands/scenario_deploy.rs
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_protocol::{Category, Example, LabeledError, Signature, Span, SyntaxShape, Value};
|
||||||
|
|
||||||
|
use crate::OncePlugin;
|
||||||
|
|
||||||
|
pub struct ScenarioDeploy;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for ScenarioDeploy {
|
||||||
|
type Plugin = OncePlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"once scenario.deploy"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Deploy once scenarios on local or remote servers."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extra_usage(&self) -> &str {
|
||||||
|
r#" Lifecycle actions:
|
||||||
|
init - init remote scenario dir
|
||||||
|
up - Create and start scenario
|
||||||
|
stop - Stop scenario
|
||||||
|
start - Start scenario if stopped
|
||||||
|
down - Stop and shut down scenario
|
||||||
|
deinit - Cleanup/remove remote and local scenario dir (leave config untouched)
|
||||||
|
|
||||||
|
Service actions:
|
||||||
|
test - Test the running scenario
|
||||||
|
updateconfig - update local scenario config"#
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
// The signature defines the usage of the command inside Nu, and also automatically
|
||||||
|
// generates its help page.
|
||||||
|
Signature::build(self.name())
|
||||||
|
.required("scenario", SyntaxShape::String, "Use available scenario")
|
||||||
|
.required(
|
||||||
|
"action",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"Actions [init,up,start,stop,down,deinit,test,updateconfig]",
|
||||||
|
)
|
||||||
|
.switch("verbose", "Set verbosity for command", Some('v'))
|
||||||
|
.switch("silent", "Set silent mode for command", Some('s'))
|
||||||
|
.category(Category::Experimental)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_terms(&self) -> Vec<&str> {
|
||||||
|
vec!["once", "scenario", "deploy"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
vec![
|
||||||
|
Example {
|
||||||
|
example: "once scenario.deploy localhost/certbot init -s",
|
||||||
|
description: "Initialize scenario 'localhost/certbot' silently.",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
example: "once scenario.deploy localhost/certbot up -v",
|
||||||
|
description: "Create and start scenario 'localhost/certbot' in verbose mode.",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
_plugin: &OncePlugin,
|
||||||
|
_engine: &EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
let head = call.head;
|
||||||
|
let scenario: String = call.req(0)?;
|
||||||
|
let action: String = call.req(1)?;
|
||||||
|
let verbose = call.has_flag("verbose")?;
|
||||||
|
let silent = call.has_flag("silent")?;
|
||||||
|
|
||||||
|
println!("Silent: {:?}, Verbose: {:?}", silent, verbose);
|
||||||
|
|
||||||
|
match action.as_str() {
|
||||||
|
"init" => action_init(scenario, head),
|
||||||
|
"up" => action_up(scenario, head),
|
||||||
|
"start" => action_start(scenario, head),
|
||||||
|
"stop" => action_stop(scenario, head),
|
||||||
|
"down" => action_down(scenario, head),
|
||||||
|
"deinit" => action_deinit(scenario, head),
|
||||||
|
"test" => action_test(scenario, head),
|
||||||
|
"updateconfig" => action_updateconfig(scenario, head),
|
||||||
|
_ => Ok(Value::String {
|
||||||
|
val: String::from("The calling action is not implemented."),
|
||||||
|
internal_span: head,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_init(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'init' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_up(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'up' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_start(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'start' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_stop(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'stop' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_down(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'down' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_deinit(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'deinit' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_test(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!("Action 'test' for scenario '{}' was triggered.", scenario),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn action_updateconfig(scenario: String, head: Span) -> Result<Value, LabeledError> {
|
||||||
|
Ok(Value::String {
|
||||||
|
val: format!(
|
||||||
|
"Action 'updateconfig' for scenario '{}' was triggered.",
|
||||||
|
scenario
|
||||||
|
),
|
||||||
|
internal_span: head,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_examples() -> Result<(), nu_protocol::ShellError> {
|
||||||
|
use nu_plugin_test_support::PluginTest;
|
||||||
|
PluginTest::new("once", OncePlugin.into())?.test_command_examples(&ScenarioDeploy)
|
||||||
|
}
|
25
crates/nu_plugin_once/src/lib.rs
Normal file
25
crates/nu_plugin_once/src/lib.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
use nu_plugin::{Plugin, PluginCommand};
|
||||||
|
|
||||||
|
mod commands;
|
||||||
|
mod once;
|
||||||
|
|
||||||
|
pub use commands::*;
|
||||||
|
pub use once::OncePlugin;
|
||||||
|
|
||||||
|
impl Plugin for OncePlugin {
|
||||||
|
fn version(&self) -> String {
|
||||||
|
env!("CARGO_PKG_VERSION").into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn commands(&self) -> Vec<Box<dyn PluginCommand<Plugin = Self>>> {
|
||||||
|
// This is a list of all of the commands you would like Nu to register when your plugin is
|
||||||
|
// loaded.
|
||||||
|
//
|
||||||
|
// If it doesn't appear on this list, it won't be added.
|
||||||
|
vec![
|
||||||
|
Box::new(Main),
|
||||||
|
Box::new(Scenario),
|
||||||
|
Box::new(ScenarioDeploy)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
30
crates/nu_plugin_once/src/main.rs
Normal file
30
crates/nu_plugin_once/src/main.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
use nu_plugin::{serve_plugin, MsgPackSerializer};
|
||||||
|
use nu_plugin_once::OncePlugin;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// When defining your plugin, you can select the Serializer that could be
|
||||||
|
// used to encode and decode the messages. The available options are
|
||||||
|
// MsgPackSerializer and JsonSerializer. Both are defined in the serializer
|
||||||
|
// folder in nu-plugin.
|
||||||
|
serve_plugin(&OncePlugin {}, MsgPackSerializer {})
|
||||||
|
|
||||||
|
// Note
|
||||||
|
// When creating plugins in other languages one needs to consider how a plugin
|
||||||
|
// is added and used in nushell.
|
||||||
|
// The steps are:
|
||||||
|
// - The plugin is register. In this stage nushell calls the binary file of
|
||||||
|
// the plugin sending information using the encoded PluginCall::PluginSignature object.
|
||||||
|
// Use this encoded data in your plugin to design the logic that will return
|
||||||
|
// the encoded signatures.
|
||||||
|
// Nushell is expecting and encoded PluginResponse::PluginSignature with all the
|
||||||
|
// plugin signatures
|
||||||
|
// - When calling the plugin, nushell sends to the binary file the encoded
|
||||||
|
// PluginCall::CallInfo which has all the call information, such as the
|
||||||
|
// values of the arguments, the name of the signature called and the input
|
||||||
|
// from the pipeline.
|
||||||
|
// Use this data to design your plugin login and to create the value that
|
||||||
|
// will be sent to nushell
|
||||||
|
// Nushell expects an encoded PluginResponse::Value from the plugin
|
||||||
|
// - If an error needs to be sent back to nushell, one can encode PluginResponse::Error.
|
||||||
|
// This is a labeled error that nushell can format for pretty printing
|
||||||
|
}
|
53
crates/nu_plugin_once/src/once.rs
Normal file
53
crates/nu_plugin_once/src/once.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
use nu_plugin::EvaluatedCall;
|
||||||
|
use nu_protocol::{LabeledError, Value};
|
||||||
|
|
||||||
|
pub struct OncePlugin;
|
||||||
|
|
||||||
|
impl OncePlugin {
|
||||||
|
pub fn print_values(
|
||||||
|
&self,
|
||||||
|
index: u32,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
input: &Value,
|
||||||
|
) -> Result<(), LabeledError> {
|
||||||
|
// Note. When debugging your plugin, you may want to print something to the console
|
||||||
|
// Use the eprintln macro to print your messages. Trying to print to stdout will
|
||||||
|
// cause a decoding error for your message
|
||||||
|
eprintln!("Calling test {index} signature");
|
||||||
|
eprintln!("value received {input:?}");
|
||||||
|
|
||||||
|
// To extract the arguments from the Call object you can use the functions req, has_flag,
|
||||||
|
// opt, rest, and get_flag
|
||||||
|
//
|
||||||
|
// Note that plugin calls only accept simple arguments, this means that you can
|
||||||
|
// pass to the plug in Int and String. This should be improved when the plugin has
|
||||||
|
// the ability to call back to NuShell to extract more information
|
||||||
|
// Keep this in mind when designing your plugin signatures
|
||||||
|
let a: i64 = call.req(0)?;
|
||||||
|
let b: String = call.req(1)?;
|
||||||
|
let flag = call.has_flag("flag")?;
|
||||||
|
let opt: Option<i64> = call.opt(2)?;
|
||||||
|
let named: Option<String> = call.get_flag("named")?;
|
||||||
|
let rest: Vec<String> = call.rest(3)?;
|
||||||
|
|
||||||
|
eprintln!("Required values");
|
||||||
|
eprintln!("a: {a:}");
|
||||||
|
eprintln!("b: {b:}");
|
||||||
|
eprintln!("flag: {flag:}");
|
||||||
|
eprintln!("rest: {rest:?}");
|
||||||
|
|
||||||
|
if let Some(v) = opt {
|
||||||
|
eprintln!("Found optional value opt: {v:}")
|
||||||
|
} else {
|
||||||
|
eprintln!("No optional value found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(v) = named {
|
||||||
|
eprintln!("Named value: {v:?}")
|
||||||
|
} else {
|
||||||
|
eprintln!("No named value found")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user