nushell/crates/nu-plugin/src/protocol/mod.rs

128 lines
3.9 KiB
Rust
Raw Normal View History

mod evaluated_call;
Add CustomValue support to plugins (#6070) * Skeleton implementation Lots and lots of TODOs * Bootstrap simple CustomValue plugin support test * Create nu_plugin_custom_value * Skeleton for nu_plugin_custom_values * Return a custom value from plugin * Encode CustomValues from plugin calls as PluginResponse::PluginData * Add new PluginCall variant CollapseCustomValue * Handle CollapseCustomValue plugin calls * Add CallInput::Data variant to CallInfo inputs * Handle CallInfo with CallInput::Data plugin calls * Send CallInput::Data if Value is PluginCustomValue from plugin calls * Remove unnecessary boxing of plugins CallInfo * Add fields needed to collapse PluginCustomValue to it * Document PluginCustomValue and its purpose * Impl collapsing using plugin calls in PluginCustomValue::to_base_value * Implement proper typetag based deserialization for CoolCustomValue * Test demonstrating that passing back a custom value to plugin works * Added a failing test for describing plugin CustomValues * Support describe for PluginCustomValues - Add name to PluginResponse::PluginData - Also turn it into a struct for clarity - Add name to PluginCustomValue - Return name field from PluginCustomValue * Demonstrate that plugins can create and handle multiple CustomValues * Add bincode to nu-plugin dependencies This is for demonstration purposes, any schemaless binary seralization format will work. I picked bincode since it's the most popular for Rust but there are defintely better options out there for this usecase * serde_json::Value -> Vec<u8> * Update capnp schema for new CallInfo.input field * Move call_input capnp serialization and deserialization into new file * Deserialize Value's span from Value itself instead of passing call.head I am not sure if this was correct and I am breaking it or if it was a bug, I don't fully understand how nu creates and uses Spans. What should reuse spans and what should recreate new ones? But yeah it felt weird that the Value's Span was being ignored since in the json serializer just uses the Value's Span * Add call_info value round trip test * Add capnp CallInput::Data serialization and deserialization support * Add CallInfo::CollapseCustomValue to capnp schema * Add capnp PluginCall::CollapseCustomValue serialization and deserialization support * Add PluginResponse::PluginData to capnp schema * Add capnp PluginResponse::PluginData serialization and deserialization support * Switch plugins::custom_values tests to capnp Both json and capnp would work now! Sadly I can't choose both at the same time :( * Add missing JsonSerializer round trip tests * Handle plugin returning PluginData as a response to CollapseCustomValue * Refactor plugin calling into a reusable function Many less levels of indentation now! * Export PluginData from nu_plugin So plugins can create their very own serve_plugin with whatever CustomValue behavior they may desire * Error if CustomValue cannot be handled by Plugin
2022-07-25 18:32:56 +02:00
mod plugin_custom_value;
mod plugin_data;
pub use evaluated_call::EvaluatedCall;
Make plugin commands support examples. (#7984) # Description As title, we can't provide examples for plugin commands, this pr would make it possible # User-Facing Changes Take plugin `nu-example-1` as example: ``` ❯ nu-example-1 -h PluginSignature test 1 for plugin. Returns Value::Nothing Usage: > nu-example-1 {flags} <a> <b> (opt) ...(rest) Flags: -h, --help - Display the help message for this command -f, --flag - a flag for the signature -n, --named <String> - named string Parameters: a <int>: required integer value b <string>: required string value (optional) opt <int>: Optional number ...rest <string>: rest value string Examples: running example with an int value and string value > nu-example-1 3 bb ``` The examples session is newly added. ## Basic idea behind these changes when nushell query plugin signatures, plugin just returns it's signature without any examples, so nushell have no idea about the examples of plugin commands. To adding the feature, we just making plugin returns it's signature with examples. Before: ``` 1. get signature ----------------> Nushell ------------------ Plugin <----------------- 2. returns Vec<Signature> ``` After: ``` 1. get signature ----------------> Nushell ------------------ Plugin <----------------- 2. returns Vec<PluginSignature> ``` When writing plugin signature to $nu.plugin-path: Serialize `<PluginSignature>` rather than `<Signature>`, which would enable us to serialize examples to `$nu.plugin-path` ## Shortcoming It's a breaking changes because `Plugin::signature` is changed, and it requires plugin authors to change their code for new signatures. Fortunally it should be easy to change, for rust based plugin, we just need to make a global replace from word `Signature` to word `PluginSignature` in their plugin project. Our content of plugin-path is really large, if one plugin have many examples, it'd results to larger body of $nu.plugin-path, which is not really scale. A solution would be save register information in other binary formats rather than `json`. But I think it'd be another story. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
2023-02-08 23:14:18 +01:00
use nu_protocol::{PluginSignature, ShellError, Span, Value};
Add CustomValue support to plugins (#6070) * Skeleton implementation Lots and lots of TODOs * Bootstrap simple CustomValue plugin support test * Create nu_plugin_custom_value * Skeleton for nu_plugin_custom_values * Return a custom value from plugin * Encode CustomValues from plugin calls as PluginResponse::PluginData * Add new PluginCall variant CollapseCustomValue * Handle CollapseCustomValue plugin calls * Add CallInput::Data variant to CallInfo inputs * Handle CallInfo with CallInput::Data plugin calls * Send CallInput::Data if Value is PluginCustomValue from plugin calls * Remove unnecessary boxing of plugins CallInfo * Add fields needed to collapse PluginCustomValue to it * Document PluginCustomValue and its purpose * Impl collapsing using plugin calls in PluginCustomValue::to_base_value * Implement proper typetag based deserialization for CoolCustomValue * Test demonstrating that passing back a custom value to plugin works * Added a failing test for describing plugin CustomValues * Support describe for PluginCustomValues - Add name to PluginResponse::PluginData - Also turn it into a struct for clarity - Add name to PluginCustomValue - Return name field from PluginCustomValue * Demonstrate that plugins can create and handle multiple CustomValues * Add bincode to nu-plugin dependencies This is for demonstration purposes, any schemaless binary seralization format will work. I picked bincode since it's the most popular for Rust but there are defintely better options out there for this usecase * serde_json::Value -> Vec<u8> * Update capnp schema for new CallInfo.input field * Move call_input capnp serialization and deserialization into new file * Deserialize Value's span from Value itself instead of passing call.head I am not sure if this was correct and I am breaking it or if it was a bug, I don't fully understand how nu creates and uses Spans. What should reuse spans and what should recreate new ones? But yeah it felt weird that the Value's Span was being ignored since in the json serializer just uses the Value's Span * Add call_info value round trip test * Add capnp CallInput::Data serialization and deserialization support * Add CallInfo::CollapseCustomValue to capnp schema * Add capnp PluginCall::CollapseCustomValue serialization and deserialization support * Add PluginResponse::PluginData to capnp schema * Add capnp PluginResponse::PluginData serialization and deserialization support * Switch plugins::custom_values tests to capnp Both json and capnp would work now! Sadly I can't choose both at the same time :( * Add missing JsonSerializer round trip tests * Handle plugin returning PluginData as a response to CollapseCustomValue * Refactor plugin calling into a reusable function Many less levels of indentation now! * Export PluginData from nu_plugin So plugins can create their very own serve_plugin with whatever CustomValue behavior they may desire * Error if CustomValue cannot be handled by Plugin
2022-07-25 18:32:56 +02:00
pub use plugin_custom_value::PluginCustomValue;
pub use plugin_data::PluginData;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct CallInfo {
pub name: String,
pub call: EvaluatedCall,
Add CustomValue support to plugins (#6070) * Skeleton implementation Lots and lots of TODOs * Bootstrap simple CustomValue plugin support test * Create nu_plugin_custom_value * Skeleton for nu_plugin_custom_values * Return a custom value from plugin * Encode CustomValues from plugin calls as PluginResponse::PluginData * Add new PluginCall variant CollapseCustomValue * Handle CollapseCustomValue plugin calls * Add CallInput::Data variant to CallInfo inputs * Handle CallInfo with CallInput::Data plugin calls * Send CallInput::Data if Value is PluginCustomValue from plugin calls * Remove unnecessary boxing of plugins CallInfo * Add fields needed to collapse PluginCustomValue to it * Document PluginCustomValue and its purpose * Impl collapsing using plugin calls in PluginCustomValue::to_base_value * Implement proper typetag based deserialization for CoolCustomValue * Test demonstrating that passing back a custom value to plugin works * Added a failing test for describing plugin CustomValues * Support describe for PluginCustomValues - Add name to PluginResponse::PluginData - Also turn it into a struct for clarity - Add name to PluginCustomValue - Return name field from PluginCustomValue * Demonstrate that plugins can create and handle multiple CustomValues * Add bincode to nu-plugin dependencies This is for demonstration purposes, any schemaless binary seralization format will work. I picked bincode since it's the most popular for Rust but there are defintely better options out there for this usecase * serde_json::Value -> Vec<u8> * Update capnp schema for new CallInfo.input field * Move call_input capnp serialization and deserialization into new file * Deserialize Value's span from Value itself instead of passing call.head I am not sure if this was correct and I am breaking it or if it was a bug, I don't fully understand how nu creates and uses Spans. What should reuse spans and what should recreate new ones? But yeah it felt weird that the Value's Span was being ignored since in the json serializer just uses the Value's Span * Add call_info value round trip test * Add capnp CallInput::Data serialization and deserialization support * Add CallInfo::CollapseCustomValue to capnp schema * Add capnp PluginCall::CollapseCustomValue serialization and deserialization support * Add PluginResponse::PluginData to capnp schema * Add capnp PluginResponse::PluginData serialization and deserialization support * Switch plugins::custom_values tests to capnp Both json and capnp would work now! Sadly I can't choose both at the same time :( * Add missing JsonSerializer round trip tests * Handle plugin returning PluginData as a response to CollapseCustomValue * Refactor plugin calling into a reusable function Many less levels of indentation now! * Export PluginData from nu_plugin So plugins can create their very own serve_plugin with whatever CustomValue behavior they may desire * Error if CustomValue cannot be handled by Plugin
2022-07-25 18:32:56 +02:00
pub input: CallInput,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub enum CallInput {
Value(Value),
Data(PluginData),
}
// Information sent to the plugin
#[derive(Serialize, Deserialize, Debug)]
pub enum PluginCall {
Signature,
Add CustomValue support to plugins (#6070) * Skeleton implementation Lots and lots of TODOs * Bootstrap simple CustomValue plugin support test * Create nu_plugin_custom_value * Skeleton for nu_plugin_custom_values * Return a custom value from plugin * Encode CustomValues from plugin calls as PluginResponse::PluginData * Add new PluginCall variant CollapseCustomValue * Handle CollapseCustomValue plugin calls * Add CallInput::Data variant to CallInfo inputs * Handle CallInfo with CallInput::Data plugin calls * Send CallInput::Data if Value is PluginCustomValue from plugin calls * Remove unnecessary boxing of plugins CallInfo * Add fields needed to collapse PluginCustomValue to it * Document PluginCustomValue and its purpose * Impl collapsing using plugin calls in PluginCustomValue::to_base_value * Implement proper typetag based deserialization for CoolCustomValue * Test demonstrating that passing back a custom value to plugin works * Added a failing test for describing plugin CustomValues * Support describe for PluginCustomValues - Add name to PluginResponse::PluginData - Also turn it into a struct for clarity - Add name to PluginCustomValue - Return name field from PluginCustomValue * Demonstrate that plugins can create and handle multiple CustomValues * Add bincode to nu-plugin dependencies This is for demonstration purposes, any schemaless binary seralization format will work. I picked bincode since it's the most popular for Rust but there are defintely better options out there for this usecase * serde_json::Value -> Vec<u8> * Update capnp schema for new CallInfo.input field * Move call_input capnp serialization and deserialization into new file * Deserialize Value's span from Value itself instead of passing call.head I am not sure if this was correct and I am breaking it or if it was a bug, I don't fully understand how nu creates and uses Spans. What should reuse spans and what should recreate new ones? But yeah it felt weird that the Value's Span was being ignored since in the json serializer just uses the Value's Span * Add call_info value round trip test * Add capnp CallInput::Data serialization and deserialization support * Add CallInfo::CollapseCustomValue to capnp schema * Add capnp PluginCall::CollapseCustomValue serialization and deserialization support * Add PluginResponse::PluginData to capnp schema * Add capnp PluginResponse::PluginData serialization and deserialization support * Switch plugins::custom_values tests to capnp Both json and capnp would work now! Sadly I can't choose both at the same time :( * Add missing JsonSerializer round trip tests * Handle plugin returning PluginData as a response to CollapseCustomValue * Refactor plugin calling into a reusable function Many less levels of indentation now! * Export PluginData from nu_plugin So plugins can create their very own serve_plugin with whatever CustomValue behavior they may desire * Error if CustomValue cannot be handled by Plugin
2022-07-25 18:32:56 +02:00
CallInfo(CallInfo),
CollapseCustomValue(PluginData),
}
Plugin api docs (#9452) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Added comments to support API docs for the `nu-plugin` crate. Removed a few items that I'd expect should only be used internally to Nushell from the documentation and reduced the visibility of some items that did not need to be public. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> There should be no user facing impact. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> Standard tests run. Additionally numerous doctests were added to the `nu-plugin` crate. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> No changes to the website necessary.
2023-06-16 16:25:40 +02:00
/// An error message with debugging information that can be passed to Nushell from the plugin
///
/// The `LabeledError` struct is a structured error message that can be returned from
/// a [Plugin](crate::Plugin)'s [`run`](crate::Plugin::run()) method. It contains
/// the error message along with optional [Span] data to support highlighting in the
/// shell.
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct LabeledError {
Plugin api docs (#9452) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Added comments to support API docs for the `nu-plugin` crate. Removed a few items that I'd expect should only be used internally to Nushell from the documentation and reduced the visibility of some items that did not need to be public. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> There should be no user facing impact. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> Standard tests run. Additionally numerous doctests were added to the `nu-plugin` crate. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> No changes to the website necessary.
2023-06-16 16:25:40 +02:00
/// The name of the error
pub label: String,
Plugin api docs (#9452) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Added comments to support API docs for the `nu-plugin` crate. Removed a few items that I'd expect should only be used internally to Nushell from the documentation and reduced the visibility of some items that did not need to be public. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> There should be no user facing impact. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> Standard tests run. Additionally numerous doctests were added to the `nu-plugin` crate. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> No changes to the website necessary.
2023-06-16 16:25:40 +02:00
/// A detailed error description
pub msg: String,
Plugin api docs (#9452) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Added comments to support API docs for the `nu-plugin` crate. Removed a few items that I'd expect should only be used internally to Nushell from the documentation and reduced the visibility of some items that did not need to be public. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> There should be no user facing impact. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> Standard tests run. Additionally numerous doctests were added to the `nu-plugin` crate. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> No changes to the website necessary.
2023-06-16 16:25:40 +02:00
/// The [Span] in which the error occurred
pub span: Option<Span>,
}
impl From<LabeledError> for ShellError {
fn from(error: LabeledError) -> Self {
match error.span {
Some(span) => ShellError::GenericError {
error: error.label,
msg: error.msg,
span: Some(span),
help: None,
inner: vec![],
},
None => ShellError::GenericError {
error: error.label,
msg: "".into(),
span: None,
help: Some(error.msg),
inner: vec![],
},
}
}
}
impl From<ShellError> for LabeledError {
fn from(error: ShellError) -> Self {
match error {
ShellError::GenericError {
error: label,
msg,
span,
..
} => LabeledError { label, msg, span },
2023-03-06 18:33:09 +01:00
ShellError::CantConvert {
to_type: expected,
from_type: input,
span,
help: _help,
} => LabeledError {
label: format!("Can't convert to {expected}"),
msg: format!("can't convert from {input} to {expected}"),
span: Some(span),
},
ShellError::DidYouMean { suggestion, span } => LabeledError {
label: "Name not found".into(),
msg: format!("did you mean '{suggestion}'?"),
span: Some(span),
},
ShellError::PluginFailedToLoad { msg } => LabeledError {
label: "Plugin failed to load".into(),
msg,
span: None,
},
ShellError::PluginFailedToEncode { msg } => LabeledError {
label: "Plugin failed to encode".into(),
msg,
span: None,
},
ShellError::PluginFailedToDecode { msg } => LabeledError {
label: "Plugin failed to decode".into(),
msg,
span: None,
},
err => LabeledError {
label: "Error - Add to LabeledError From<ShellError>".into(),
msg: err.to_string(),
span: None,
},
}
}
}
// Information received from the plugin
Plugin api docs (#9452) <!-- if this PR closes one or more issues, you can automatically link the PR with them by using one of the [*linking keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword), e.g. - this PR should close #xxxx - fixes #xxxx you can also mention related issues, PRs or discussions! --> # Description <!-- Thank you for improving Nushell. Please, check our [contributing guide](../CONTRIBUTING.md) and talk to the core team before making major changes. Description of your pull request goes here. **Provide examples and/or screenshots** if your changes affect the user experience. --> Added comments to support API docs for the `nu-plugin` crate. Removed a few items that I'd expect should only be used internally to Nushell from the documentation and reduced the visibility of some items that did not need to be public. # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> There should be no user facing impact. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- crates/nu-std/tests/run.nu` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> Standard tests run. Additionally numerous doctests were added to the `nu-plugin` crate. # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> No changes to the website necessary.
2023-06-16 16:25:40 +02:00
// Needs to be public to communicate with nu-parser but not typically
// used by Plugin authors
#[doc(hidden)]
#[derive(Serialize, Deserialize)]
pub enum PluginResponse {
Error(LabeledError),
Make plugin commands support examples. (#7984) # Description As title, we can't provide examples for plugin commands, this pr would make it possible # User-Facing Changes Take plugin `nu-example-1` as example: ``` ❯ nu-example-1 -h PluginSignature test 1 for plugin. Returns Value::Nothing Usage: > nu-example-1 {flags} <a> <b> (opt) ...(rest) Flags: -h, --help - Display the help message for this command -f, --flag - a flag for the signature -n, --named <String> - named string Parameters: a <int>: required integer value b <string>: required string value (optional) opt <int>: Optional number ...rest <string>: rest value string Examples: running example with an int value and string value > nu-example-1 3 bb ``` The examples session is newly added. ## Basic idea behind these changes when nushell query plugin signatures, plugin just returns it's signature without any examples, so nushell have no idea about the examples of plugin commands. To adding the feature, we just making plugin returns it's signature with examples. Before: ``` 1. get signature ----------------> Nushell ------------------ Plugin <----------------- 2. returns Vec<Signature> ``` After: ``` 1. get signature ----------------> Nushell ------------------ Plugin <----------------- 2. returns Vec<PluginSignature> ``` When writing plugin signature to $nu.plugin-path: Serialize `<PluginSignature>` rather than `<Signature>`, which would enable us to serialize examples to `$nu.plugin-path` ## Shortcoming It's a breaking changes because `Plugin::signature` is changed, and it requires plugin authors to change their code for new signatures. Fortunally it should be easy to change, for rust based plugin, we just need to make a global replace from word `Signature` to word `PluginSignature` in their plugin project. Our content of plugin-path is really large, if one plugin have many examples, it'd results to larger body of $nu.plugin-path, which is not really scale. A solution would be save register information in other binary formats rather than `json`. But I think it'd be another story. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
2023-02-08 23:14:18 +01:00
Signature(Vec<PluginSignature>),
Value(Box<Value>),
Add CustomValue support to plugins (#6070) * Skeleton implementation Lots and lots of TODOs * Bootstrap simple CustomValue plugin support test * Create nu_plugin_custom_value * Skeleton for nu_plugin_custom_values * Return a custom value from plugin * Encode CustomValues from plugin calls as PluginResponse::PluginData * Add new PluginCall variant CollapseCustomValue * Handle CollapseCustomValue plugin calls * Add CallInput::Data variant to CallInfo inputs * Handle CallInfo with CallInput::Data plugin calls * Send CallInput::Data if Value is PluginCustomValue from plugin calls * Remove unnecessary boxing of plugins CallInfo * Add fields needed to collapse PluginCustomValue to it * Document PluginCustomValue and its purpose * Impl collapsing using plugin calls in PluginCustomValue::to_base_value * Implement proper typetag based deserialization for CoolCustomValue * Test demonstrating that passing back a custom value to plugin works * Added a failing test for describing plugin CustomValues * Support describe for PluginCustomValues - Add name to PluginResponse::PluginData - Also turn it into a struct for clarity - Add name to PluginCustomValue - Return name field from PluginCustomValue * Demonstrate that plugins can create and handle multiple CustomValues * Add bincode to nu-plugin dependencies This is for demonstration purposes, any schemaless binary seralization format will work. I picked bincode since it's the most popular for Rust but there are defintely better options out there for this usecase * serde_json::Value -> Vec<u8> * Update capnp schema for new CallInfo.input field * Move call_input capnp serialization and deserialization into new file * Deserialize Value's span from Value itself instead of passing call.head I am not sure if this was correct and I am breaking it or if it was a bug, I don't fully understand how nu creates and uses Spans. What should reuse spans and what should recreate new ones? But yeah it felt weird that the Value's Span was being ignored since in the json serializer just uses the Value's Span * Add call_info value round trip test * Add capnp CallInput::Data serialization and deserialization support * Add CallInfo::CollapseCustomValue to capnp schema * Add capnp PluginCall::CollapseCustomValue serialization and deserialization support * Add PluginResponse::PluginData to capnp schema * Add capnp PluginResponse::PluginData serialization and deserialization support * Switch plugins::custom_values tests to capnp Both json and capnp would work now! Sadly I can't choose both at the same time :( * Add missing JsonSerializer round trip tests * Handle plugin returning PluginData as a response to CollapseCustomValue * Refactor plugin calling into a reusable function Many less levels of indentation now! * Export PluginData from nu_plugin So plugins can create their very own serve_plugin with whatever CustomValue behavior they may desire * Error if CustomValue cannot be handled by Plugin
2022-07-25 18:32:56 +02:00
PluginData(String, PluginData),
}