use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
use nu_protocol::{
Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, SyntaxShape, Type,
Value, shell_error::generic::GenericError,
};
use polars::{prelude::NamedFrom, series::Series};
use uuid::Uuid;
use crate::{
PolarsPlugin,
values::{CustomValueSupport, NuDataFrame, PolarsPluginType},
};
#[derive(Clone)]
pub struct CacheGet;
impl PluginCommand for CacheGet {
type Plugin = PolarsPlugin;
fn name(&self) -> &str {
"polars store-get"
}
fn description(&self) -> &str {
"Gets a Dataframe or other object from the plugin cache."
}
fn signature(&self) -> Signature {
Signature::build(self.name())
.required("key", SyntaxShape::String, "Key of objects to get.")
.input_output_types(
PolarsPluginType::types()
.iter()
.map(|t| (Type::Any, Type::from(*t)))
.collect(),
)
.category(Category::Custom("dataframe".into()))
}
fn examples(&self) -> Vec<Example<'_>> {
vec![Example {
description: "Get a stored object",
example: r#"let df = ([[a b];[1 2] [3 4]] | polars into-df);
polars store-ls | get key | first | polars store-get $in"#,
result: Some(
NuDataFrame::try_from_series_vec(
vec![
Series::new("a".into(), &[1_i64, 3]),
Series::new("b".into(), &[2_i64, 4]),
],
Span::test_data(),
)
.expect("could not create dataframe")
.into_value(Span::test_data()),
),
}]
}
fn run(
&self,
plugin: &Self::Plugin,
_engine: &EngineInterface,
call: &EvaluatedCall,
_input: PipelineData,
) -> Result<PipelineData, LabeledError> {
let key = call
.req::<String>(0)
.and_then(|ref k| as_uuid(k, call.head))?;
let value = if let Some(cache_value) = plugin.cache.get(&key, true)? {
let polars_object = cache_value.value;
polars_object.into_value(call.head)
} else {
Value::nothing(call.head)
};
Ok(PipelineData::value(value, None))
}
}
fn as_uuid(s: &str, span: Span) -> Result<Uuid, ShellError> {
Uuid::parse_str(s).map_err(|e| {
ShellError::Generic(GenericError::new(
format!("Failed to convert key string to UUID: {e}"),
"",
span,
))
})
}
#[cfg(test)]
mod test {
use super::*;
use crate::test::test_polars_plugin_command_with_decls;
use nu_command::{First, Get};
#[test]
fn test_examples() -> Result<(), ShellError> {
test_polars_plugin_command_with_decls(&CacheGet, vec![Box::new(Get), Box::new(First)])
}
}