nu_plugin_plotters 0.2.5+0.111.0

A nushell plugin for for plotting charts
Documentation
use nu_engine::command_prelude::*;
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
use nu_protocol::{FromValue, LabeledError, PipelineMetadata};
use plotters::prelude::{IntoDrawingArea, SVGBackend};

use crate::value;

#[derive(Debug, Clone)]
pub struct DrawSvg;

impl Command for DrawSvg {
    fn name(&self) -> &str {
        "draw svg"
    }

    fn signature(&self) -> Signature {
        Signature::new(Command::name(self))
            .add_help()
            .description(Command::description(self))
            .search_terms(
                Command::search_terms(self)
                    .into_iter()
                    .map(ToOwned::to_owned)
                    .collect(),
            )
            .input_output_type(value::Chart2d::ty(), Type::String)
    }

    fn description(&self) -> &str {
        "Draws a chart on a SVG string."
    }

    fn search_terms(&self) -> Vec<&str> {
        vec!["plotters", "chart", "2d", "draw", "svg"]
    }

    fn run(
        &self,
        _: &EngineState,
        _: &mut Stack,
        call: &Call,
        input: PipelineData,
    ) -> Result<PipelineData, ShellError> {
        DrawSvg::run(self, input, call.head)
    }
}

impl PluginCommand for DrawSvg {
    type Plugin = crate::plugin::PlottersPlugin;

    fn name(&self) -> &str {
        Command::name(self)
    }

    fn signature(&self) -> Signature {
        Command::signature(self)
    }

    fn description(&self) -> &str {
        Command::description(self)
    }

    fn search_terms(&self) -> Vec<&str> {
        Command::search_terms(self)
    }

    fn run(
        &self,
        _: &Self::Plugin,
        _: &EngineInterface,
        call: &EvaluatedCall,
        input: PipelineData,
    ) -> Result<PipelineData, LabeledError> {
        Ok(DrawSvg::run(self, input, call.head)?)
    }
}

impl DrawSvg {
    const CONTENT_TYPE: mime2::Mime = mime2::image::SVG_XML;

    fn run(&self, input: PipelineData, span: Span) -> Result<PipelineData, ShellError> {
        let input = input.into_value(span)?;
        let span = input.span();
        let chart = value::Chart2d::from_value(input)?;

        let mut output = String::new();
        let drawing_backend = SVGBackend::with_string(&mut output, (chart.width, chart.height));
        super::draw(chart, drawing_backend.into_drawing_area());

        Ok(PipelineData::Value(
            Value::string(output, span),
            Some(
                PipelineMetadata::default().with_content_type(Some(Self::CONTENT_TYPE.to_string())),
            ),
        ))
    }
}