diff --git a/crates/nu_plugin_example/src/commands/config.rs b/crates/nu_plugin_example/src/commands/config.rs index f549bd324f..7716e27537 100644 --- a/crates/nu_plugin_example/src/commands/config.rs +++ b/crates/nu_plugin_example/src/commands/config.rs @@ -1,10 +1,37 @@ +use std::path::PathBuf; + use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand}; -use nu_protocol::{Category, LabeledError, Signature, Type, Value}; +use nu_protocol::{Category, FromValue, LabeledError, Signature, Spanned, Type, Value}; use crate::ExamplePlugin; pub struct Config; +/// Example config struct. +/// +/// Using the `FromValue` derive macro, structs can be easily loaded from [`Value`]s, +/// similar to serde's `Deserialize` macro. +/// This is handy for plugin configs or piped data. +/// All fields must implement [`FromValue`]. +/// For [`Option`] fields, they can be omitted in the config. +/// +/// This example shows that nested and spanned data work too, so you can describe nested +/// structures and get spans of values wrapped in [`Spanned`]. +/// Since this config uses only `Option`s, no field is required in the config. +#[allow(dead_code)] +#[derive(Debug, FromValue)] +struct PluginConfig { + path: Option>, + nested: Option, +} + +#[allow(dead_code)] +#[derive(Debug, FromValue)] +struct SubConfig { + bool: bool, + string: String, +} + impl SimplePluginCommand for Config { type Plugin = ExamplePlugin; @@ -39,7 +66,11 @@ impl SimplePluginCommand for Config { ) -> Result { let config = engine.get_plugin_config()?; match config { - Some(config) => Ok(config.clone()), + Some(value) => { + let config = PluginConfig::from_value(value.clone())?; + println!("got config {config:?}"); + Ok(value) + } None => Err(LabeledError::new("No config sent").with_label( "configuration for this plugin was not found in `$env.config.plugins.example`", call.head, diff --git a/crates/nu_plugin_example/src/commands/two.rs b/crates/nu_plugin_example/src/commands/two.rs index fcf2bf75ff..e02465e8b7 100644 --- a/crates/nu_plugin_example/src/commands/two.rs +++ b/crates/nu_plugin_example/src/commands/two.rs @@ -1,5 +1,5 @@ use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand}; -use nu_protocol::{record, Category, LabeledError, Signature, SyntaxShape, Value}; +use nu_protocol::{Category, IntoValue, LabeledError, Signature, SyntaxShape, Value}; use crate::ExamplePlugin; @@ -38,14 +38,22 @@ impl SimplePluginCommand for Two { ) -> Result { plugin.print_values(2, call, input)?; + // Use the IntoValue derive macro and trait to easily design output data. + #[derive(IntoValue)] + struct Output { + one: i64, + two: i64, + three: i64, + } + let vals = (0..10i64) .map(|i| { - let record = record! { - "one" => Value::int(i, call.head), - "two" => Value::int(2 * i, call.head), - "three" => Value::int(3 * i, call.head), - }; - Value::record(record, call.head) + Output { + one: i, + two: 2 * i, + three: 3 * i, + } + .into_value(call.head) }) .collect(); diff --git a/tests/plugins/config.rs b/tests/plugins/config.rs index 44f2797ceb..b110d2a7fd 100644 --- a/tests/plugins/config.rs +++ b/tests/plugins/config.rs @@ -1,27 +1,5 @@ use nu_test_support::nu_with_plugins; -#[test] -fn closure() { - let actual = nu_with_plugins!( - cwd: "tests", - plugin: ("nu_plugin_example"), - r#" - $env.env_value = "value from env" - - $env.config = { - plugins: { - example: {|| - $env.env_value - } - } - } - example config - "# - ); - - assert!(actual.out.contains("value from env")); -} - #[test] fn none() { let actual = nu_with_plugins!( @@ -34,7 +12,7 @@ fn none() { } #[test] -fn record() { +fn some() { let actual = nu_with_plugins!( cwd: "tests", plugin: ("nu_plugin_example"), @@ -42,8 +20,11 @@ fn record() { $env.config = { plugins: { example: { - key1: "value" - key2: "other" + path: "some/path", + nested: { + bool: true, + string: "Hello Example!" + } } } } @@ -51,6 +32,6 @@ fn record() { "# ); - assert!(actual.out.contains("value")); - assert!(actual.out.contains("other")); + assert!(actual.out.contains("some/path")); + assert!(actual.out.contains("Hello Example!")); }