diff --git a/crates/old/nu_plugin_chart/Cargo.toml b/crates/old/nu_plugin_chart/Cargo.toml deleted file mode 100644 index 26f7f5ff62..0000000000 --- a/crates/old/nu_plugin_chart/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A plugin to display charts" -edition = "2018" -license = "MIT" -name = "nu_plugin_chart" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -nu-data = { path="../nu-data", version = "0.73.1" } -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -nu-value-ext = { path="../nu-value-ext", version = "0.73.1" } - -crossterm = "0.19.0" -tui = { version="0.15.0", default-features=false, features=["crossterm"] } diff --git a/crates/old/nu_plugin_chart/src/bar.rs b/crates/old/nu_plugin_chart/src/bar.rs deleted file mode 100644 index 4a77d0eca5..0000000000 --- a/crates/old/nu_plugin_chart/src/bar.rs +++ /dev/null @@ -1,119 +0,0 @@ -use nu_data::utils::Model; -use nu_errors::ShellError; - -use tui::{ - layout::{Constraint, Direction, Layout}, - style::{Color, Modifier, Style}, - widgets::BarChart, -}; - -const DEFAULT_COLOR: Color = Color::Green; - -pub struct Bar<'a> { - pub title: &'a str, - pub data: Vec<(&'a str, u64)>, - pub enhanced_graphics: bool, -} - -impl<'a> Bar<'a> { - pub fn from_model(model: &'a Model) -> Result, ShellError> { - let mut data = Vec::new(); - let mut data_points = Vec::new(); - - for percentages in model - .percentages - .table_entries() - .cloned() - .collect::>() - { - let mut percentages_collected = vec![]; - - for percentage in percentages.table_entries().cloned().collect::>() { - percentages_collected.push(percentage.as_u64()?); - } - - data_points.push(percentages_collected); - } - - let mark_in = if model.labels.y.len() <= 1 { - 0 - } else { - (model.labels.y.len() as f64 / 2.0).floor() as usize - }; - - for idx in 0..model.labels.x.len() { - let mut current = 0; - - loop { - let label = if current == mark_in { - model - .labels - .at(idx) - .ok_or_else(|| ShellError::untagged_runtime_error("Could not load data"))? - } else { - "" - }; - - let percentages_collected = data_points - .get(current) - .ok_or_else(|| ShellError::untagged_runtime_error("Could not load data"))?; - - data.push(( - label, - *percentages_collected - .get(idx) - .ok_or_else(|| ShellError::untagged_runtime_error("Could not load data"))?, - )); - - current += 1; - - if current == model.labels.y.len() { - break; - } - } - } - - Ok(Bar { - title: "Bar Chart", - data: (&data[..]).to_vec(), - enhanced_graphics: true, - }) - } - - pub fn draw(&mut self, ui: &mut tui::Terminal) -> std::io::Result<()> - where - T: tui::backend::Backend, - { - ui.draw(|f| { - let chunks = Layout::default() - .direction(Direction::Vertical) - .margin(0) - .constraints([Constraint::Percentage(100)].as_ref()) - .split(f.size()); - - let barchart = BarChart::default() - .data(&self.data) - .bar_width(9) - .bar_style(Style::default().fg(DEFAULT_COLOR)) - .value_style( - Style::default() - .bg(Color::Black) - .add_modifier(Modifier::BOLD), - ); - - f.render_widget(barchart, chunks[0]); - })?; - Ok(()) - } - - pub fn on_right(&mut self) { - let one_bar = self.data.remove(0); - self.data.push(one_bar); - } - - pub fn on_left(&mut self) { - if let Some(one_bar) = self.data.pop() { - self.data.insert(0, one_bar); - } - } -} diff --git a/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_bar.rs b/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_bar.rs deleted file mode 100644 index 20ada96668..0000000000 --- a/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_bar.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_chart::ChartBar; - -fn main() { - serve_plugin(&mut ChartBar::new()); -} diff --git a/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_line.rs b/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_line.rs deleted file mode 100644 index 82ae4a00db..0000000000 --- a/crates/old/nu_plugin_chart/src/bin/nu_plugin_chart_line.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_chart::ChartLine; - -fn main() { - serve_plugin(&mut ChartLine::new()); -} diff --git a/crates/old/nu_plugin_chart/src/lib.rs b/crates/old/nu_plugin_chart/src/lib.rs deleted file mode 100644 index 747c5bdcd4..0000000000 --- a/crates/old/nu_plugin_chart/src/lib.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod bar; -mod line; -mod nu; - -pub use nu::{ChartBar, ChartLine}; diff --git a/crates/old/nu_plugin_chart/src/line.rs b/crates/old/nu_plugin_chart/src/line.rs deleted file mode 100644 index 53088a70d4..0000000000 --- a/crates/old/nu_plugin_chart/src/line.rs +++ /dev/null @@ -1,144 +0,0 @@ -use nu_data::utils::Model; -use nu_errors::ShellError; - -use tui::{ - layout::{Constraint, Direction, Layout}, - style::{Color, Modifier, Style}, - symbols, - text::Span, - widgets::{Axis, Chart, Dataset, GraphType}, -}; - -const DEFAULT_COLOR: Color = Color::Green; - -const DEFAULT_LINE_COLORS: [Color; 5] = [ - Color::Green, - Color::Cyan, - Color::Magenta, - Color::Yellow, - Color::Red, -]; - -#[derive(Debug)] -pub struct Line { - x_labels: Vec, - x_range: [f64; 2], - y_range: [f64; 2], - datasets_names: Vec, - data: Vec>, -} - -impl<'a> Line { - pub fn from_model(model: &'a Model) -> Result { - Ok(Line { - x_labels: model.labels.x.to_vec(), - x_range: [ - model.ranges.0.start.as_u64()? as f64, - model.labels.x.len() as f64, - ], - y_range: [ - model.ranges.1.start.as_u64()? as f64, - model.ranges.1.end.as_u64()? as f64, - ], - datasets_names: if model.labels.y.len() == 1 { - vec!["".to_string()] - } else { - model.labels.y.to_vec() - }, - data: model - .data - .table_entries() - .collect::>() - .iter() - .map(|subset| { - subset - .table_entries() - .enumerate() - .map(|(idx, data_point)| { - ( - idx as f64, - if let Ok(point) = data_point.as_u64() { - point as f64 - } else { - 0.0 - }, - ) - }) - .collect::>() - }) - .collect::>(), - }) - } - - pub fn draw(&mut self, ui: &mut tui::Terminal) -> std::io::Result<()> - where - T: tui::backend::Backend, - { - ui.draw(|f| { - let chunks = Layout::default() - .direction(Direction::Vertical) - .margin(1) - .constraints([Constraint::Percentage(100)].as_ref()) - .split(f.size()); - - let x_labels = self - .x_labels - .iter() - .map(move |label| { - Span::styled(label, Style::default().add_modifier(Modifier::BOLD)) - }) - .collect::>(); - - let y_labels = vec![ - Span::styled( - self.y_range[0].to_string(), - Style::default().add_modifier(Modifier::BOLD), - ), - Span::raw(((self.y_range[0] + self.y_range[1]) / 2.0).to_string()), - Span::styled( - self.y_range[1].to_string(), - Style::default().add_modifier(Modifier::BOLD), - ), - ]; - - let marker = if x_labels.len() > 60 { - symbols::Marker::Braille - } else { - symbols::Marker::Dot - }; - - let datasets = self - .data - .iter() - .enumerate() - .map(|(idx, data_series)| { - Dataset::default() - .name(&self.datasets_names[idx]) - .marker(marker) - .graph_type(GraphType::Line) - .style( - Style::default() - .fg(*DEFAULT_LINE_COLORS.get(idx).unwrap_or(&DEFAULT_COLOR)), - ) - .data(data_series) - }) - .collect(); - - let chart = Chart::new(datasets) - .x_axis( - Axis::default() - .style(Style::default().fg(Color::Gray)) - .labels(x_labels) - .bounds(self.x_range), - ) - .y_axis( - Axis::default() - .style(Style::default().fg(Color::Gray)) - .labels(y_labels) - .bounds(self.y_range), - ); - f.render_widget(chart, chunks[0]); - })?; - Ok(()) - } -} diff --git a/crates/old/nu_plugin_chart/src/nu.rs b/crates/old/nu_plugin_chart/src/nu.rs deleted file mode 100644 index 7b472a1675..0000000000 --- a/crates/old/nu_plugin_chart/src/nu.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod bar; -mod line; - -pub use bar::SubCommand as ChartBar; -pub use line::SubCommand as ChartLine; diff --git a/crates/old/nu_plugin_chart/src/nu/bar.rs b/crates/old/nu_plugin_chart/src/nu/bar.rs deleted file mode 100644 index 9d06c896ee..0000000000 --- a/crates/old/nu_plugin_chart/src/nu/bar.rs +++ /dev/null @@ -1,371 +0,0 @@ -use nu_data::utils::{report as build_report, Model}; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, ColumnPath, Primitive, Signature, SyntaxShape, UntaggedValue, Value}; -use nu_source::{Tagged, TaggedItem}; -use nu_value_ext::ValueExt; - -use crate::bar::Bar; - -use std::{ - error::Error, - io::stdout, - sync::mpsc, - thread, - time::{Duration, Instant}, -}; - -use crossterm::{ - event::{self, DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, -}; - -use tui::{backend::CrosstermBackend, Terminal}; - -enum Event { - Input(I), - Tick, -} - -pub enum Columns { - One(Tagged), - Two(Tagged, Tagged), - None, -} - -#[allow(clippy::type_complexity)] -pub struct SubCommand { - pub reduction: nu_data::utils::Reduction, - pub columns: Columns, - pub eval: Option Result + Send>>, - pub format: Option, -} - -impl Default for SubCommand { - fn default() -> Self { - Self::new() - } -} - -impl SubCommand { - pub fn new() -> SubCommand { - SubCommand { - reduction: nu_data::utils::Reduction::Count, - columns: Columns::None, - eval: None, - format: None, - } - } -} - -fn display(model: &Model) -> Result<(), Box> { - let mut app = Bar::from_model(model)?; - - enable_raw_mode()?; - - let mut stdout = stdout(); - execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; - - let backend = CrosstermBackend::new(stdout); - - let mut terminal = Terminal::new(backend)?; - - let (tx, rx) = mpsc::channel(); - - let tick_rate = Duration::from_millis(250); - thread::spawn(move || { - let mut last_tick = Instant::now(); - loop { - if event::poll(tick_rate - last_tick.elapsed()).is_ok() { - if let Ok(CEvent::Key(key)) = event::read() { - let _ = tx.send(Event::Input(key)); - } - } - if last_tick.elapsed() >= tick_rate { - let _ = tx.send(Event::Tick); - last_tick = Instant::now(); - } - } - }); - - terminal.clear()?; - - loop { - app.draw(&mut terminal)?; - - match rx.recv()? { - Event::Input(event) => match event.code { - KeyCode::Left => app.on_left(), - KeyCode::Right => app.on_right(), - KeyCode::Char('q') => { - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - break; - } - _ => { - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - break; - } - }, - Event::Tick => {} - } - } - - Ok(()) -} - -impl Plugin for SubCommand { - fn config(&mut self) -> Result { - Ok(Signature::build("chart bar") - .usage("Bar charts") - .switch("acc", "accumulate values", Some('a')) - .optional( - "columns", - SyntaxShape::Any, - "the columns to chart [x-axis y-axis]", - ) - .named( - "use", - SyntaxShape::ColumnPath, - "column to use for evaluation", - Some('u'), - ) - .named( - "format", - SyntaxShape::String, - "Specify date and time formatting", - Some('f'), - )) - } - - fn sink(&mut self, call_info: CallInfo, input: Vec) { - if let Some(Value { - value: UntaggedValue::Primitive(Primitive::Boolean(true)), - .. - }) = call_info.args.get("acc") - { - self.reduction = nu_data::utils::Reduction::Accumulate; - } - - let _ = self.run(call_info, input); - } -} - -impl SubCommand { - fn run(&mut self, call_info: CallInfo, input: Vec) -> Result<(), ShellError> { - let args = call_info.args; - let name = call_info.name_tag; - - self.eval = if let Some(path) = args.get("use") { - Some(evaluator(path.as_column_path()?.item)) - } else { - None - }; - - self.format = if let Some(fmt) = args.get("format") { - Some(fmt.as_string()?) - } else { - None - }; - - for arg in args.positional_iter() { - match arg { - Value { - value: UntaggedValue::Primitive(Primitive::String(column)), - tag, - } => { - let column = column.clone(); - self.columns = Columns::One(column.tagged(tag)); - } - Value { - value: UntaggedValue::Table(arguments), - tag, - } => { - if arguments.len() > 1 { - let col1 = arguments - .get(0) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - let col2 = arguments - .get(1) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - self.columns = Columns::Two(col1, col2); - } else { - let col1 = arguments - .get(0) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - self.columns = Columns::One(col1); - } - } - _ => {} - } - } - - let data = UntaggedValue::table(&input).into_value(&name); - - match &self.columns { - Columns::Two(col1, col2) => { - let key = col1.clone(); - let fmt = self.format.clone(); - - let grouper = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - let fmt = fmt.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => { - if let Some(fmt) = fmt { - let callback = nu_data::utils::helpers::date_formatter(fmt); - callback(&key, "nothing".to_string()) - } else { - nu_value_ext::as_string(&key) - } - } - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let key = col2.clone(); - let splitter = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => nu_value_ext::as_string(&key), - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let formatter = if self.format.is_some() { - let default = String::from("%b-%Y"); - - let string_fmt = self.format.as_ref().unwrap_or(&default); - - Some(nu_data::utils::helpers::date_formatter( - string_fmt.to_string(), - )) - } else { - None - }; - - let options = nu_data::utils::Operation { - grouper: Some(grouper), - splitter: Some(splitter), - format: &formatter, - eval: &self.eval, - reduction: &self.reduction, - }; - - let _ = display(&build_report(&data, options, &name)?); - } - Columns::One(col) => { - let key = col.clone(); - let fmt = self.format.clone(); - - let grouper = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - let fmt = fmt.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => { - if let Some(fmt) = fmt { - let callback = nu_data::utils::helpers::date_formatter(fmt); - callback(&key, "nothing".to_string()) - } else { - nu_value_ext::as_string(&key) - } - } - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let formatter = if self.format.is_some() { - let default = String::from("%b-%Y"); - - let string_fmt = self.format.as_ref().unwrap_or(&default); - - Some(nu_data::utils::helpers::date_formatter( - string_fmt.to_string(), - )) - } else { - None - }; - - let options = nu_data::utils::Operation { - grouper: Some(grouper), - splitter: None, - format: &formatter, - eval: &self.eval, - reduction: &self.reduction, - }; - - let _ = display(&build_report(&data, options, &name)?); - } - _ => {} - } - - Ok(()) - } -} - -pub fn evaluator(by: ColumnPath) -> Box Result + Send> { - Box::new(move |_: usize, value: &Value| { - let path = by.clone(); - - let eval = nu_value_ext::get_data_by_column_path(value, &path, move |_, _, error| error); - - match eval { - Ok(with_value) => Ok(with_value), - Err(reason) => Err(reason), - } - }) -} diff --git a/crates/old/nu_plugin_chart/src/nu/line.rs b/crates/old/nu_plugin_chart/src/nu/line.rs deleted file mode 100644 index 86911a77dc..0000000000 --- a/crates/old/nu_plugin_chart/src/nu/line.rs +++ /dev/null @@ -1,369 +0,0 @@ -use nu_data::utils::{report as build_report, Model}; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, ColumnPath, Primitive, Signature, SyntaxShape, UntaggedValue, Value}; -use nu_source::{Tagged, TaggedItem}; -use nu_value_ext::ValueExt; - -use crate::line::Line; - -use std::{ - error::Error, - io::stdout, - sync::mpsc, - thread, - time::{Duration, Instant}, -}; - -use crossterm::{ - event::{self, DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode}, - execute, - terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, -}; - -use tui::{backend::CrosstermBackend, Terminal}; - -enum Event { - Input(I), - Tick, -} - -pub enum Columns { - One(Tagged), - Two(Tagged, Tagged), - None, -} - -#[allow(clippy::type_complexity)] -pub struct SubCommand { - pub reduction: nu_data::utils::Reduction, - pub columns: Columns, - pub eval: Option Result + Send>>, - pub format: Option, -} - -impl Default for SubCommand { - fn default() -> Self { - Self::new() - } -} - -impl SubCommand { - pub fn new() -> SubCommand { - SubCommand { - reduction: nu_data::utils::Reduction::Count, - columns: Columns::None, - eval: None, - format: None, - } - } -} - -fn display(model: &Model) -> Result<(), Box> { - let mut app = Line::from_model(model)?; - - enable_raw_mode()?; - - let mut stdout = stdout(); - execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; - - let backend = CrosstermBackend::new(stdout); - - let mut terminal = Terminal::new(backend)?; - - let (tx, rx) = mpsc::channel(); - - let tick_rate = Duration::from_millis(250); - thread::spawn(move || { - let mut last_tick = Instant::now(); - loop { - if event::poll(tick_rate - last_tick.elapsed()).is_ok() { - if let Ok(CEvent::Key(key)) = event::read() { - let _ = tx.send(Event::Input(key)); - } - } - if last_tick.elapsed() >= tick_rate { - let _ = tx.send(Event::Tick); - last_tick = Instant::now(); - } - } - }); - - terminal.clear()?; - - loop { - app.draw(&mut terminal)?; - - match rx.recv()? { - Event::Input(event) => match event.code { - KeyCode::Char('q') => { - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - break; - } - _ => { - disable_raw_mode()?; - execute!( - terminal.backend_mut(), - LeaveAlternateScreen, - DisableMouseCapture - )?; - terminal.show_cursor()?; - break; - } - }, - Event::Tick => {} - } - } - - Ok(()) -} - -impl Plugin for SubCommand { - fn config(&mut self) -> Result { - Ok(Signature::build("chart line") - .usage("Line charts") - .switch("acc", "accumulate values", Some('a')) - .optional( - "columns", - SyntaxShape::Any, - "the columns to chart [x-axis y-axis]", - ) - .named( - "use", - SyntaxShape::ColumnPath, - "column to use for evaluation", - Some('u'), - ) - .named( - "format", - SyntaxShape::String, - "Specify date and time formatting", - Some('f'), - )) - } - - fn sink(&mut self, call_info: CallInfo, input: Vec) { - if let Some(Value { - value: UntaggedValue::Primitive(Primitive::Boolean(true)), - .. - }) = call_info.args.get("acc") - { - self.reduction = nu_data::utils::Reduction::Accumulate; - } - - let _ = self.run(call_info, input); - } -} - -impl SubCommand { - fn run(&mut self, call_info: CallInfo, input: Vec) -> Result<(), ShellError> { - let args = call_info.args; - let name = call_info.name_tag; - - self.eval = if let Some(path) = args.get("use") { - Some(evaluator(path.as_column_path()?.item)) - } else { - None - }; - - self.format = if let Some(fmt) = args.get("format") { - Some(fmt.as_string()?) - } else { - None - }; - - for arg in args.positional_iter() { - match arg { - Value { - value: UntaggedValue::Primitive(Primitive::String(column)), - tag, - } => { - let column = column.clone(); - self.columns = Columns::One(column.tagged(tag)); - } - Value { - value: UntaggedValue::Table(arguments), - tag, - } => { - if arguments.len() > 1 { - let col1 = arguments - .get(0) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - let col2 = arguments - .get(1) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - self.columns = Columns::Two(col1, col2); - } else { - let col1 = arguments - .get(0) - .ok_or_else(|| { - ShellError::labeled_error( - "expected file and replace strings eg) [find replace]", - "missing find-replace values", - tag, - ) - })? - .as_string()? - .tagged(tag); - - self.columns = Columns::One(col1); - } - } - _ => {} - } - } - - let data = UntaggedValue::table(&input).into_value(&name); - - match &self.columns { - Columns::Two(col1, col2) => { - let key = col1.clone(); - let fmt = self.format.clone(); - - let grouper = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - let fmt = fmt.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => { - if let Some(fmt) = fmt { - let callback = nu_data::utils::helpers::date_formatter(fmt); - callback(&key, "nothing".to_string()) - } else { - nu_value_ext::as_string(&key) - } - } - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let key = col2.clone(); - let splitter = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => nu_value_ext::as_string(&key), - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let formatter = if self.format.is_some() { - let default = String::from("%b-%Y"); - - let string_fmt = self.format.as_ref().unwrap_or(&default); - - Some(nu_data::utils::helpers::date_formatter( - string_fmt.to_string(), - )) - } else { - None - }; - - let options = nu_data::utils::Operation { - grouper: Some(grouper), - splitter: Some(splitter), - format: &formatter, - eval: &self.eval, - reduction: &self.reduction, - }; - - let _ = display(&build_report(&data, options, &name)?); - } - Columns::One(col) => { - let key = col.clone(); - let fmt = self.format.clone(); - - let grouper = Box::new(move |_: usize, row: &Value| { - let key = key.clone(); - let fmt = fmt.clone(); - - match row.get_data_by_key(key.borrow_spanned()) { - Some(key) => { - if let Some(fmt) = fmt { - let callback = nu_data::utils::helpers::date_formatter(fmt); - callback(&key, "nothing".to_string()) - } else { - nu_value_ext::as_string(&key) - } - } - None => Err(ShellError::labeled_error( - "unknown column", - "unknown column", - key.tag(), - )), - } - }); - - let formatter = if self.format.is_some() { - let default = String::from("%b-%Y"); - - let string_fmt = self.format.as_ref().unwrap_or(&default); - - Some(nu_data::utils::helpers::date_formatter( - string_fmt.to_string(), - )) - } else { - None - }; - - let options = nu_data::utils::Operation { - grouper: Some(grouper), - splitter: None, - format: &formatter, - eval: &self.eval, - reduction: &self.reduction, - }; - - let _ = display(&build_report(&data, options, &name)?); - } - _ => {} - } - - Ok(()) - } -} - -pub fn evaluator(by: ColumnPath) -> Box Result + Send> { - Box::new(move |_: usize, value: &Value| { - let path = by.clone(); - - let eval = nu_value_ext::get_data_by_column_path(value, &path, move |_, _, error| error); - - match eval { - Ok(with_value) => Ok(with_value), - Err(reason) => Err(reason), - } - }) -} diff --git a/crates/old/nu_plugin_from_bson/Cargo.toml b/crates/old/nu_plugin_from_bson/Cargo.toml deleted file mode 100644 index b54e0a30cd..0000000000 --- a/crates/old/nu_plugin_from_bson/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A converter plugin to the bson format for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_from_bson" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -bigdecimal = { package = "bigdecimal", version = "0.3.0", features = ["serde"] } -bson = { version = "2.0.1", features = [ "chrono-0_4" ] } -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } - -[build-dependencies] diff --git a/crates/old/nu_plugin_from_bson/src/from_bson.rs b/crates/old/nu_plugin_from_bson/src/from_bson.rs deleted file mode 100644 index 115c52492e..0000000000 --- a/crates/old/nu_plugin_from_bson/src/from_bson.rs +++ /dev/null @@ -1,212 +0,0 @@ -use bigdecimal::BigDecimal; -use bson::{spec::BinarySubtype, Bson}; -use nu_errors::{ExpectedRange, ShellError}; -use nu_protocol::{Primitive, ReturnSuccess, ReturnValue, TaggedDictBuilder, UntaggedValue, Value}; -use nu_source::{SpannedItem, Tag}; -use std::str::FromStr; - -#[derive(Default)] -pub struct FromBson { - pub state: Vec, - pub name_tag: Tag, -} - -impl FromBson { - pub fn new() -> FromBson { - FromBson { - state: vec![], - name_tag: Tag::unknown(), - } - } -} - -fn bson_array(input: &[Bson], tag: Tag) -> Result, ShellError> { - let mut out = vec![]; - - for value in input { - out.push(convert_bson_value_to_nu_value(value, &tag)?); - } - - Ok(out) -} - -fn convert_bson_value_to_nu_value(v: &Bson, tag: impl Into) -> Result { - let tag = tag.into(); - let span = tag.span; - - Ok(match v { - Bson::Double(n) => UntaggedValue::Primitive(Primitive::from(*n)).into_value(&tag), - Bson::String(s) => { - UntaggedValue::Primitive(Primitive::String(String::from(s))).into_value(&tag) - } - Bson::Array(a) => UntaggedValue::Table(bson_array(a, tag.clone())?).into_value(&tag), - Bson::Document(doc) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - for (k, v) in doc { - collected.insert_value(k.clone(), convert_bson_value_to_nu_value(v, &tag)?); - } - - collected.into_value() - } - Bson::Boolean(b) => UntaggedValue::Primitive(Primitive::Boolean(*b)).into_value(&tag), - Bson::Null => UntaggedValue::Primitive(Primitive::Nothing).into_value(&tag), - Bson::RegularExpression(regx) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$regex".to_string(), - UntaggedValue::Primitive(Primitive::String(String::from(®x.pattern))) - .into_value(&tag), - ); - collected.insert_value( - "$options".to_string(), - UntaggedValue::Primitive(Primitive::String(String::from(®x.options))) - .into_value(&tag), - ); - collected.into_value() - } - Bson::Int32(n) => UntaggedValue::int(*n).into_value(&tag), - Bson::Int64(n) => UntaggedValue::int(*n).into_value(&tag), - Bson::Decimal128(n) => { - // TODO: this really isn't great, and we should update this to do a higher - // fidelity translation - let decimal = BigDecimal::from_str(&n.to_string()).map_err(|_| { - ShellError::range_error( - ExpectedRange::BigDecimal, - &n.spanned(span), - "converting BSON Decimal128 to BigDecimal".to_owned(), - ) - })?; - UntaggedValue::Primitive(Primitive::Decimal(decimal)).into_value(&tag) - } - Bson::JavaScriptCode(js) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$javascript".to_string(), - UntaggedValue::Primitive(Primitive::String(String::from(js))).into_value(&tag), - ); - collected.into_value() - } - Bson::JavaScriptCodeWithScope(js) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$javascript".to_string(), - UntaggedValue::Primitive(Primitive::String(String::from(&js.code))) - .into_value(&tag), - ); - collected.insert_value( - "$scope".to_string(), - convert_bson_value_to_nu_value(&Bson::Document(js.scope.to_owned()), tag)?, - ); - collected.into_value() - } - Bson::Timestamp(ts) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$timestamp".to_string(), - UntaggedValue::int(ts.time).into_value(&tag), - ); - collected.into_value() - } - Bson::Binary(binary) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$binary_subtype".to_string(), - match binary.subtype { - BinarySubtype::UserDefined(u) => UntaggedValue::int(u), - _ => UntaggedValue::Primitive(Primitive::String(binary_subtype_to_string( - binary.subtype, - ))), - } - .into_value(&tag), - ); - collected.insert_value( - "$binary".to_string(), - UntaggedValue::Primitive(Primitive::Binary(binary.bytes.to_owned())) - .into_value(&tag), - ); - collected.into_value() - } - Bson::ObjectId(obj_id) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$object_id".to_string(), - UntaggedValue::Primitive(Primitive::String(obj_id.to_hex())).into_value(&tag), - ); - collected.into_value() - } - Bson::DateTime(dt) => { - UntaggedValue::Primitive(Primitive::Date(dt.to_chrono().into())).into_value(&tag) - } - Bson::Symbol(s) => { - let mut collected = TaggedDictBuilder::new(tag.clone()); - collected.insert_value( - "$symbol".to_string(), - UntaggedValue::Primitive(Primitive::String(String::from(s))).into_value(&tag), - ); - collected.into_value() - } - Bson::Undefined | Bson::MaxKey | Bson::MinKey | Bson::DbPointer(_) => { - // TODO Impelmenting Bson::Undefined, Bson::MaxKey, Bson::MinKey and Bson::DbPointer - // These Variants weren't present in the previous version. - TaggedDictBuilder::new(tag).into_value() - } - }) -} - -fn binary_subtype_to_string(bst: BinarySubtype) -> String { - match bst { - BinarySubtype::Generic => "generic", - BinarySubtype::Function => "function", - BinarySubtype::BinaryOld => "binary_old", - BinarySubtype::UuidOld => "uuid_old", - BinarySubtype::Uuid => "uuid", - BinarySubtype::Md5 => "md5", - _ => unreachable!(), - } - .to_string() -} - -#[derive(Debug)] -struct BytesReader { - pos: usize, - inner: Vec, -} - -impl BytesReader { - fn new(bytes: Vec) -> BytesReader { - BytesReader { - pos: 0, - inner: bytes, - } - } -} - -impl std::io::Read for BytesReader { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - let src: &mut &[u8] = &mut self.inner[self.pos..].as_ref(); - let diff = src.read(buf)?; - self.pos += diff; - Ok(diff) - } -} - -pub fn from_bson_bytes_to_value(bytes: Vec, tag: impl Into) -> Result { - let mut docs = Vec::new(); - let mut b_reader = BytesReader::new(bytes); - while let Ok(v) = bson::de::from_reader(&mut b_reader) { - docs.push(Bson::Document(v)); - } - - convert_bson_value_to_nu_value(&Bson::Array(docs), tag) -} - -pub fn from_bson(bytes: Vec, name_tag: Tag) -> Result, ShellError> { - match from_bson_bytes_to_value(bytes, name_tag.clone()) { - Ok(x) => Ok(vec![ReturnSuccess::value(x)]), - Err(_) => Err(ShellError::labeled_error( - "Could not parse as BSON", - "input cannot be parsed as BSON", - name_tag, - )), - } -} diff --git a/crates/old/nu_plugin_from_bson/src/lib.rs b/crates/old/nu_plugin_from_bson/src/lib.rs deleted file mode 100644 index c037ee0289..0000000000 --- a/crates/old/nu_plugin_from_bson/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod from_bson; -mod nu; - -pub use from_bson::FromBson; diff --git a/crates/old/nu_plugin_from_bson/src/main.rs b/crates/old/nu_plugin_from_bson/src/main.rs deleted file mode 100644 index bec813d017..0000000000 --- a/crates/old/nu_plugin_from_bson/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_from_bson::FromBson; - -fn main() { - serve_plugin(&mut FromBson::new()) -} diff --git a/crates/old/nu_plugin_from_bson/src/nu/mod.rs b/crates/old/nu_plugin_from_bson/src/nu/mod.rs deleted file mode 100644 index a9f8bd496e..0000000000 --- a/crates/old/nu_plugin_from_bson/src/nu/mod.rs +++ /dev/null @@ -1,46 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::FromBson; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, Primitive, ReturnValue, Signature, UntaggedValue, Value}; -use nu_source::Tag; - -impl Plugin for FromBson { - fn config(&mut self) -> Result { - Ok(Signature::build("from bson") - .usage("Convert from .bson binary into table") - .filter()) - } - - fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { - self.name_tag = call_info.name_tag; - Ok(vec![]) - } - - fn filter(&mut self, input: Value) -> Result, ShellError> { - match input { - Value { - value: UntaggedValue::Primitive(Primitive::Binary(b)), - .. - } => { - self.state.extend_from_slice(&b); - } - Value { tag, .. } => { - return Err(ShellError::labeled_error_with_secondary( - "Expected binary from pipeline", - "requires binary input", - self.name_tag.clone(), - "value originates from here", - tag, - )); - } - } - Ok(vec![]) - } - - fn end_filter(&mut self) -> Result, ShellError> { - crate::from_bson::from_bson(self.state.clone(), Tag::unknown()) - } -} diff --git a/crates/old/nu_plugin_from_bson/src/nu/tests.rs b/crates/old/nu_plugin_from_bson/src/nu/tests.rs deleted file mode 100644 index d14c19bee3..0000000000 --- a/crates/old/nu_plugin_from_bson/src/nu/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod integration {} diff --git a/crates/old/nu_plugin_from_mp4/Cargo.toml b/crates/old/nu_plugin_from_mp4/Cargo.toml deleted file mode 100644 index 6113fb0c48..0000000000 --- a/crates/old/nu_plugin_from_mp4/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A converter plugin to the mp4 format for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_from_mp4" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -tempfile = "3.2.0" -mp4 = "0.9.0" - -[build-dependencies] diff --git a/crates/old/nu_plugin_from_mp4/src/from_mp4.rs b/crates/old/nu_plugin_from_mp4/src/from_mp4.rs deleted file mode 100644 index 671cc29339..0000000000 --- a/crates/old/nu_plugin_from_mp4/src/from_mp4.rs +++ /dev/null @@ -1,174 +0,0 @@ -use nu_errors::ShellError; -use nu_protocol::{ReturnSuccess, ReturnValue, TaggedDictBuilder, UntaggedValue, Value}; -use nu_source::Tag; -use std::fs::File; -use std::io::Write; -use std::path::Path; - -#[derive(Default)] -pub struct FromMp4 { - pub state: Vec, - pub name_tag: Tag, -} - -impl FromMp4 { - pub fn new() -> Self { - Self { - state: vec![], - name_tag: Tag::unknown(), - } - } -} - -pub fn convert_mp4_file_to_nu_value(path: &Path, tag: Tag) -> Result { - let mp4 = mp4::read_mp4(File::open(path).expect("Could not open mp4 file to read metadata"))?; - - let mut dict = TaggedDictBuilder::new(tag.clone()); - - // Build tracks table - let mut tracks = Vec::new(); - for track in mp4.tracks().values() { - let mut curr_track_dict = TaggedDictBuilder::new(tag.clone()); - - curr_track_dict.insert_untagged("track id", UntaggedValue::int(track.track_id())); - - curr_track_dict.insert_untagged( - "track type", - match track.track_type() { - Ok(t) => UntaggedValue::string(t.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "media type", - match track.media_type() { - Ok(t) => UntaggedValue::string(t.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "box type", - match track.box_type() { - Ok(t) => UntaggedValue::string(t.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged("width", UntaggedValue::int(track.width())); - curr_track_dict.insert_untagged("height", UntaggedValue::int(track.height())); - curr_track_dict.insert_untagged("frame_rate", UntaggedValue::from(track.frame_rate())); - - curr_track_dict.insert_untagged( - "sample freq index", - match track.sample_freq_index() { - Ok(sfi) => UntaggedValue::string(sfi.freq().to_string()), // this is a string for formatting reasons - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "channel config", - match track.channel_config() { - Ok(cc) => UntaggedValue::string(cc.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged("language", UntaggedValue::string(track.language())); - curr_track_dict.insert_untagged("timescale", UntaggedValue::int(track.timescale())); - curr_track_dict.insert_untagged( - "duration", - UntaggedValue::duration(track.duration().as_nanos()), - ); - curr_track_dict.insert_untagged("bitrate", UntaggedValue::int(track.bitrate())); - curr_track_dict.insert_untagged("sample count", UntaggedValue::int(track.sample_count())); - - curr_track_dict.insert_untagged( - "video profile", - match track.video_profile() { - Ok(vp) => UntaggedValue::string(vp.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "audio profile", - match track.audio_profile() { - Ok(ap) => UntaggedValue::string(ap.to_string()), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "sequence parameter set", - match track.sequence_parameter_set() { - Ok(sps) => UntaggedValue::string(format!("{:X?}", sps)), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - curr_track_dict.insert_untagged( - "picture parameter set", - match track.picture_parameter_set() { - Ok(pps) => UntaggedValue::string(format!("{:X?}", pps)), - Err(_) => UntaggedValue::from("Unknown"), - }, - ); - - // push curr track to tracks vec - tracks.push(curr_track_dict.into_value()); - } - - dict.insert_untagged("size", UntaggedValue::big_int(mp4.size())); - - dict.insert_untagged( - "major brand", - UntaggedValue::string(mp4.major_brand().to_string()), - ); - - dict.insert_untagged("minor version", UntaggedValue::int(mp4.minor_version())); - - dict.insert_untagged( - "compatible brands", - UntaggedValue::string(format!("{:?}", mp4.compatible_brands())), - ); - - dict.insert_untagged( - "duration", - UntaggedValue::duration(mp4.duration().as_nanos()), - ); - - dict.insert_untagged("timescale", UntaggedValue::int(mp4.timescale())); - dict.insert_untagged("is fragmented", UntaggedValue::boolean(mp4.is_fragmented())); - dict.insert_untagged("tracks", UntaggedValue::Table(tracks).into_value(&tag)); - - Ok(dict.into_value()) -} - -pub fn from_mp4_bytes_to_value(mut bytes: Vec, tag: Tag) -> Result { - let mut tempfile = tempfile::NamedTempFile::new()?; - tempfile.write_all(bytes.as_mut_slice())?; - match convert_mp4_file_to_nu_value(tempfile.path(), tag) { - Ok(value) => Ok(value), - Err(e) => Err(std::io::Error::new(std::io::ErrorKind::Other, e)), - } -} - -pub fn from_mp4(bytes: Vec, name_tag: Tag) -> Result, ShellError> { - match from_mp4_bytes_to_value(bytes, name_tag.clone()) { - Ok(x) => match x { - Value { - value: UntaggedValue::Table(list), - .. - } => Ok(list.into_iter().map(ReturnSuccess::value).collect()), - _ => Ok(vec![ReturnSuccess::value(x)]), - }, - Err(_) => Err(ShellError::labeled_error( - "Could not parse as MP4", - "input cannot be parsed as MP4", - &name_tag, - )), - } -} diff --git a/crates/old/nu_plugin_from_mp4/src/lib.rs b/crates/old/nu_plugin_from_mp4/src/lib.rs deleted file mode 100644 index 8de6281f24..0000000000 --- a/crates/old/nu_plugin_from_mp4/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod from_mp4; -mod nu; - -pub use from_mp4::FromMp4; diff --git a/crates/old/nu_plugin_from_mp4/src/main.rs b/crates/old/nu_plugin_from_mp4/src/main.rs deleted file mode 100644 index 539b494cf6..0000000000 --- a/crates/old/nu_plugin_from_mp4/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_from_mp4::FromMp4; - -fn main() { - serve_plugin(&mut FromMp4::new()) -} diff --git a/crates/old/nu_plugin_from_mp4/src/nu/mod.rs b/crates/old/nu_plugin_from_mp4/src/nu/mod.rs deleted file mode 100644 index 4e8a8144fe..0000000000 --- a/crates/old/nu_plugin_from_mp4/src/nu/mod.rs +++ /dev/null @@ -1,46 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::FromMp4; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, Primitive, ReturnValue, Signature, UntaggedValue, Value}; -use nu_source::Tag; - -impl Plugin for FromMp4 { - fn config(&mut self) -> Result { - Ok(Signature::build("from mp4") - .usage("Get meta-data of mp4 file") - .filter()) - } - - fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { - self.name_tag = call_info.name_tag; - Ok(vec![]) - } - - fn filter(&mut self, input: Value) -> Result, ShellError> { - match input { - Value { - value: UntaggedValue::Primitive(Primitive::Binary(b)), - .. - } => { - self.state.extend_from_slice(&b); - } - Value { tag, .. } => { - return Err(ShellError::labeled_error_with_secondary( - "Expected binary from pipeline", - "requires binary input", - self.name_tag.clone(), - "value originates from here", - tag, - )); - } - } - Ok(vec![]) - } - - fn end_filter(&mut self) -> Result, ShellError> { - crate::from_mp4::from_mp4(self.state.clone(), Tag::unknown()) - } -} diff --git a/crates/old/nu_plugin_from_mp4/src/nu/tests.rs b/crates/old/nu_plugin_from_mp4/src/nu/tests.rs deleted file mode 100644 index d14c19bee3..0000000000 --- a/crates/old/nu_plugin_from_mp4/src/nu/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod integration {} diff --git a/crates/old/nu_plugin_from_sqlite/Cargo.toml b/crates/old/nu_plugin_from_sqlite/Cargo.toml deleted file mode 100644 index 2535e83b95..0000000000 --- a/crates/old/nu_plugin_from_sqlite/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A converter plugin to the bson format for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_from_sqlite" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -bigdecimal = { package = "bigdecimal", version = "0.3.0", features = ["serde"] } -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -tempfile = "3.2.0" - -[dependencies.rusqlite] -features = ["bundled", "blob"] -version = "0.26.1" - -[build-dependencies] diff --git a/crates/old/nu_plugin_from_sqlite/src/from_sqlite.rs b/crates/old/nu_plugin_from_sqlite/src/from_sqlite.rs deleted file mode 100644 index da7bb00da5..0000000000 --- a/crates/old/nu_plugin_from_sqlite/src/from_sqlite.rs +++ /dev/null @@ -1,138 +0,0 @@ -use bigdecimal::FromPrimitive; -use nu_errors::ShellError; -use nu_protocol::{Primitive, ReturnSuccess, ReturnValue, TaggedDictBuilder, UntaggedValue, Value}; -use nu_source::Tag; -use rusqlite::{types::ValueRef, Connection, Row}; -use std::io::Write; -use std::path::Path; - -#[derive(Default)] -pub struct FromSqlite { - pub state: Vec, - pub name_tag: Tag, - pub tables: Vec, -} - -impl FromSqlite { - pub fn new() -> FromSqlite { - FromSqlite { - state: vec![], - name_tag: Tag::unknown(), - tables: vec![], - } - } -} - -pub fn convert_sqlite_file_to_nu_value( - path: &Path, - tag: impl Into + Clone, - tables: Vec, -) -> Result { - let conn = Connection::open(path)?; - - let mut meta_out = Vec::new(); - let mut meta_stmt = conn.prepare("select name from sqlite_master where type='table'")?; - let mut meta_rows = meta_stmt.query([])?; - - while let Some(meta_row) = meta_rows.next()? { - let table_name: String = meta_row.get(0)?; - if tables.is_empty() || tables.contains(&table_name) { - let mut meta_dict = TaggedDictBuilder::new(tag.clone()); - let mut out = Vec::new(); - let mut table_stmt = conn.prepare(&format!("select * from [{}]", table_name))?; - let mut table_rows = table_stmt.query([])?; - while let Some(table_row) = table_rows.next()? { - out.push(convert_sqlite_row_to_nu_value(table_row, tag.clone())) - } - meta_dict.insert_value( - "table_name".to_string(), - UntaggedValue::Primitive(Primitive::String(table_name)).into_value(tag.clone()), - ); - meta_dict.insert_value( - "table_values", - UntaggedValue::Table(out).into_value(tag.clone()), - ); - meta_out.push(meta_dict.into_value()); - } - } - let tag = tag.into(); - Ok(UntaggedValue::Table(meta_out).into_value(tag)) -} - -fn convert_sqlite_row_to_nu_value(row: &Row, tag: impl Into + Clone) -> Value { - let mut collected = TaggedDictBuilder::new(tag.clone()); - for (i, c) in row.as_ref().column_names().iter().enumerate() { - collected.insert_value( - c.to_string(), - convert_sqlite_value_to_nu_value(row.get_ref_unwrap(i), tag.clone()), - ); - } - collected.into_value() -} - -fn convert_sqlite_value_to_nu_value(value: ValueRef, tag: impl Into + Clone) -> Value { - match value { - ValueRef::Null => { - UntaggedValue::Primitive(Primitive::String(String::from(""))).into_value(tag) - } - ValueRef::Integer(i) => UntaggedValue::int(i).into_value(tag), - ValueRef::Real(f) => { - let f = bigdecimal::BigDecimal::from_f64(f); - let tag = tag.into(); - let span = tag.span; - match f { - Some(d) => UntaggedValue::decimal(d).into_value(tag), - None => UntaggedValue::Error(ShellError::labeled_error( - "Can not convert f64 to big decimal", - "can not convert to decimal", - span, - )) - .into_value(tag), - } - } - ValueRef::Text(s) => { - // this unwrap is safe because we know the ValueRef is Text. - UntaggedValue::Primitive(Primitive::String(String::from_utf8_lossy(s).to_string())) - .into_value(tag) - } - ValueRef::Blob(u) => UntaggedValue::binary(u.to_owned()).into_value(tag), - } -} - -pub fn from_sqlite_bytes_to_value( - mut bytes: Vec, - tag: impl Into + Clone, - tables: Vec, -) -> Result { - // FIXME: should probably write a sqlite virtual filesystem - // that will allow us to use bytes as a file to avoid this - // write out, but this will require C code. Might be - // best done as a PR to rusqlite. - let mut tempfile = tempfile::NamedTempFile::new()?; - tempfile.write_all(bytes.as_mut_slice())?; - match convert_sqlite_file_to_nu_value(tempfile.path(), tag, tables) { - Ok(value) => Ok(value), - Err(e) => Err(std::io::Error::new(std::io::ErrorKind::Other, e)), - } -} - -pub fn from_sqlite( - bytes: Vec, - name_tag: Tag, - tables: Vec, -) -> Result, ShellError> { - match from_sqlite_bytes_to_value(bytes, name_tag.clone(), tables) { - Ok(x) => match x { - Value { - value: UntaggedValue::Table(list), - .. - } => Ok(list.into_iter().map(ReturnSuccess::value).collect()), - _ => Ok(vec![ReturnSuccess::value(x)]), - }, - Err(_) => Err(ShellError::labeled_error( - "Could not parse as SQLite", - "input cannot be parsed as SQLite", - &name_tag, - )), - } -} diff --git a/crates/old/nu_plugin_from_sqlite/src/lib.rs b/crates/old/nu_plugin_from_sqlite/src/lib.rs deleted file mode 100644 index 62e49fb460..0000000000 --- a/crates/old/nu_plugin_from_sqlite/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod from_sqlite; -mod nu; - -pub use from_sqlite::FromSqlite; diff --git a/crates/old/nu_plugin_from_sqlite/src/main.rs b/crates/old/nu_plugin_from_sqlite/src/main.rs deleted file mode 100644 index 26147638a5..0000000000 --- a/crates/old/nu_plugin_from_sqlite/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_from_sqlite::FromSqlite; - -fn main() { - serve_plugin(&mut FromSqlite::new()) -} diff --git a/crates/old/nu_plugin_from_sqlite/src/nu/mod.rs b/crates/old/nu_plugin_from_sqlite/src/nu/mod.rs deleted file mode 100644 index 5abb6767f0..0000000000 --- a/crates/old/nu_plugin_from_sqlite/src/nu/mod.rs +++ /dev/null @@ -1,75 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::FromSqlite; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, Primitive, ReturnValue, Signature, SyntaxShape, UntaggedValue, Value}; -use nu_source::Tag; - -// Adapted from crates/nu-command/src/commands/dataframe/utils.rs -fn convert_columns(columns: &[Value]) -> Result, ShellError> { - let res = columns - .iter() - .map(|value| match &value.value { - UntaggedValue::Primitive(Primitive::String(s)) => Ok(s.clone()), - _ => Err(ShellError::labeled_error( - "Incorrect column format", - "Only string as column name", - &value.tag, - )), - }) - .collect::, _>>()?; - - Ok(res) -} - -impl Plugin for FromSqlite { - fn config(&mut self) -> Result { - Ok(Signature::build("from sqlite") - .named( - "tables", - SyntaxShape::Table, - "Only convert specified tables", - Some('t'), - ) - .usage("Convert from sqlite binary into table") - .filter()) - } - - fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { - self.name_tag = call_info.name_tag; - - if let Some(t) = call_info.args.get("tables") { - if let UntaggedValue::Table(columns) = t.value.clone() { - self.tables = convert_columns(columns.as_slice())?; - } - } - Ok(vec![]) - } - - fn filter(&mut self, input: Value) -> Result, ShellError> { - match input { - Value { - value: UntaggedValue::Primitive(Primitive::Binary(b)), - .. - } => { - self.state.extend_from_slice(&b); - } - Value { tag, .. } => { - return Err(ShellError::labeled_error_with_secondary( - "Expected binary from pipeline", - "requires binary input", - self.name_tag.clone(), - "value originates from here", - tag, - )); - } - } - Ok(vec![]) - } - - fn end_filter(&mut self) -> Result, ShellError> { - crate::from_sqlite::from_sqlite(self.state.clone(), Tag::unknown(), self.tables.clone()) - } -} diff --git a/crates/old/nu_plugin_from_sqlite/src/nu/tests.rs b/crates/old/nu_plugin_from_sqlite/src/nu/tests.rs deleted file mode 100644 index d14c19bee3..0000000000 --- a/crates/old/nu_plugin_from_sqlite/src/nu/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod integration {} diff --git a/crates/old/nu_plugin_s3/Cargo.toml b/crates/old/nu_plugin_s3/Cargo.toml deleted file mode 100644 index f723797fa1..0000000000 --- a/crates/old/nu_plugin_s3/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "An S3 plugin for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_s3" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -futures = { version="0.3.12", features=["compat", "io-compat"] } -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -s3handler = "0.7.5" - -[build-dependencies] diff --git a/crates/old/nu_plugin_s3/README.md b/crates/old/nu_plugin_s3/README.md deleted file mode 100644 index 60ffb3320a..0000000000 --- a/crates/old/nu_plugin_s3/README.md +++ /dev/null @@ -1,9 +0,0 @@ -Nu Plugin S3 ---- - -An S3 plugin for nu shell, it can load the content of S3 objects and convert into table - -#### Snapshot -In following example, the return content from httpbin is saved before as an object in AWS S3. -![snapshot](https://raw.githubusercontent.com/yanganto/nu_plugin_s3/master/demo.png) - diff --git a/crates/old/nu_plugin_s3/demo.png b/crates/old/nu_plugin_s3/demo.png deleted file mode 100644 index 8fd2a4162d..0000000000 Binary files a/crates/old/nu_plugin_s3/demo.png and /dev/null differ diff --git a/crates/old/nu_plugin_s3/src/handler.rs b/crates/old/nu_plugin_s3/src/handler.rs deleted file mode 100644 index ebb5c188b1..0000000000 --- a/crates/old/nu_plugin_s3/src/handler.rs +++ /dev/null @@ -1,134 +0,0 @@ -use nu_errors::ShellError; -use nu_protocol::{CallInfo, CommandAction, ReturnSuccess, ReturnValue, UntaggedValue, Value}; -use nu_source::{AnchorLocation, Tag}; -use s3handler::{CredentialConfig, Handler as S3Handler}; - -pub struct Handler { - pub resource: Option, - pub tag: Tag, - pub has_raw: bool, - pub config: CredentialConfig, -} - -impl Handler { - pub fn new() -> Handler { - Handler { - tag: Tag::unknown(), - config: CredentialConfig { - host: String::new(), - access_key: String::new(), - secret_key: String::new(), - user: None, - region: None, - s3_type: None, - secure: None, - }, - resource: None, - has_raw: false, - } - } - - pub fn setup(&mut self, call_info: CallInfo) -> ReturnValue { - self.resource = { - let r = call_info.args.nth(0).ok_or_else(|| { - ShellError::labeled_error( - "No obj or directory specified", - "for command", - &call_info.name_tag, - ) - })?; - Some(r.clone()) - }; - self.tag = call_info.name_tag.clone(); - self.has_raw = call_info.args.has("raw"); - - if let Some(e) = call_info.args.get("endpoint") { - self.config.host = e.as_string()? - } else { - return Err(ShellError::labeled_error( - "No endpoint provided", - "for command", - &call_info.name_tag, - )); - } - - if let Some(access_key) = call_info.args.get("access-key") { - self.config.access_key = access_key.as_string()? - } else { - return Err(ShellError::labeled_error( - "No access key provided", - "for command", - &call_info.name_tag, - )); - } - - if let Some(secret_key) = call_info.args.get("secret-key") { - self.config.secret_key = secret_key.as_string()? - } else { - return Err(ShellError::labeled_error( - "No secret key provided", - "for command", - &call_info.name_tag, - )); - } - - if let Some(region) = call_info.args.get("region") { - self.config.region = Some(region.as_string()?) - } - - ReturnSuccess::value(UntaggedValue::nothing().into_untagged_value()) - } -} - -impl Default for Handler { - fn default() -> Self { - Self::new() - } -} - -pub async fn s3_helper(resource: &Value, has_raw: bool, config: &CredentialConfig) -> ReturnValue { - let resource_str = resource.as_string()?; - let mut handler = S3Handler::from(config); - let (output, content_type) = handler - .cat(&resource_str) - .map_err(|e| ShellError::unexpected(e.to_string()))?; - - let extension = if has_raw { - None - } else { - fn get_accept_ext(s: String) -> Option { - if s.contains("json") { - Some("json".to_string()) - } else if s.contains("xml") { - Some("xml".to_string()) - } else if s.contains("svg") { - Some("svg".to_string()) - } else if s.contains("html") { - Some("html".to_string()) - } else { - None - } - } - // If the extension could not provide when uploading, - // try to use the resource extension. - content_type.and_then(get_accept_ext).or_else(|| { - resource_str - .split('.') - .last() - .map(String::from) - .and_then(get_accept_ext) - }) - }; - - if let Some(e) = extension { - Ok(ReturnSuccess::Action(CommandAction::AutoConvert( - UntaggedValue::string(output).into_value(Tag { - span: resource.tag.span, - anchor: Some(AnchorLocation::Url(resource_str)), - }), - e, - ))) - } else { - ReturnSuccess::value(UntaggedValue::string(output)) - } -} diff --git a/crates/old/nu_plugin_s3/src/lib.rs b/crates/old/nu_plugin_s3/src/lib.rs deleted file mode 100644 index c906216399..0000000000 --- a/crates/old/nu_plugin_s3/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod handler; -mod nu; - -pub use handler::Handler; diff --git a/crates/old/nu_plugin_s3/src/main.rs b/crates/old/nu_plugin_s3/src/main.rs deleted file mode 100644 index e3d0a58412..0000000000 --- a/crates/old/nu_plugin_s3/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_s3::handler; - -fn main() { - serve_plugin(&mut handler::Handler::new()) -} diff --git a/crates/old/nu_plugin_s3/src/nu/mod.rs b/crates/old/nu_plugin_s3/src/nu/mod.rs deleted file mode 100644 index f42c98e6c7..0000000000 --- a/crates/old/nu_plugin_s3/src/nu/mod.rs +++ /dev/null @@ -1,60 +0,0 @@ -use futures::executor::block_on; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape}; - -use crate::handler; -use crate::handler::s3_helper; - -impl Plugin for handler::Handler { - fn config(&mut self) -> Result { - Ok(Signature::build("s3") - .usage("Load S3 resource into a cell, convert to table if possible (avoid by appending '--raw' or '-R')") - .required( - "RESOURCE", - SyntaxShape::String, - "the RESOURCE to fetch the contents from", - ) - .named( - "endpoint", - SyntaxShape::Any, - "the endpoint info for the S3 resource, i.g., s3.ap-northeast-1.amazonaws.com or 10.1.1.1", - Some('e'), - ) - .named( - "access-key", - SyntaxShape::Any, - "the access key when authenticating", - Some('a'), - ) - .named( - "secret-key", - SyntaxShape::Any, - "the secret key when authenticating", - Some('s'), - ) - .named( - "region", - SyntaxShape::Any, - "the region of the resource, default will use us-east-1", - Some('r'), - ) - .switch("raw", "fetch contents as text rather than a table", Some('R')) - .filter()) - } - - fn begin_filter(&mut self, callinfo: CallInfo) -> Result, ShellError> { - self.setup(callinfo)?; - Ok(vec![block_on(s3_helper( - &self.resource.clone().ok_or_else(|| { - ShellError::labeled_error( - "internal error: resource not set", - "resource not set", - &self.tag, - ) - })?, - self.has_raw, - &self.config, - ))]) - } -} diff --git a/crates/old/nu_plugin_start/Cargo.toml b/crates/old/nu_plugin_start/Cargo.toml deleted file mode 100644 index 453dd6c76e..0000000000 --- a/crates/old/nu_plugin_start/Cargo.toml +++ /dev/null @@ -1,26 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A plugin to open files/URLs directly from Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_start" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -glob = "0.3.0" -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -url = "2.2.0" -webbrowser = "0.5.5" - -[target.'cfg(windows)'.dependencies] -open = "1.4.0" - -[build-dependencies] -nu-errors = { version = "0.73.1", path="../nu-errors" } -nu-source = { version = "0.73.1", path="../nu-source" } diff --git a/crates/old/nu_plugin_start/src/lib.rs b/crates/old/nu_plugin_start/src/lib.rs deleted file mode 100644 index de341633d3..0000000000 --- a/crates/old/nu_plugin_start/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod nu; -mod start; - -pub use start::Start; diff --git a/crates/old/nu_plugin_start/src/main.rs b/crates/old/nu_plugin_start/src/main.rs deleted file mode 100644 index 43ef421b8e..0000000000 --- a/crates/old/nu_plugin_start/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_start::Start; - -fn main() { - serve_plugin(&mut Start::new()); -} diff --git a/crates/old/nu_plugin_start/src/nu/mod.rs b/crates/old/nu_plugin_start/src/nu/mod.rs deleted file mode 100644 index b7f1849a07..0000000000 --- a/crates/old/nu_plugin_start/src/nu/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, ReturnValue, Signature, SyntaxShape}; - -use crate::start::Start; - -impl Plugin for Start { - fn config(&mut self) -> Result { - Ok(Signature::build("start") - .usage("Opens each file/directory/URL using the default application") - .rest( - "rest", - SyntaxShape::String, - "files/urls/directories to open", - ) - .named( - "application", - SyntaxShape::String, - "Specifies the application used for opening the files/directories/urls", - Some('a'), - ) - .filter()) - } - fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { - self.parse(call_info)?; - self.exec().map(|_| Vec::new()) - } -} diff --git a/crates/old/nu_plugin_start/src/start.rs b/crates/old/nu_plugin_start/src/start.rs deleted file mode 100644 index cae6bebe03..0000000000 --- a/crates/old/nu_plugin_start/src/start.rs +++ /dev/null @@ -1,260 +0,0 @@ -use nu_errors::ShellError; -use nu_protocol::{CallInfo, Value}; -use nu_source::{Tag, Tagged, TaggedItem}; -use std::path::Path; -#[cfg(not(target_os = "windows"))] -use std::process::{Command, Stdio}; - -#[derive(Default)] -pub struct Start { - pub tag: Tag, - pub filenames: Vec>, - pub application: Option, -} - -impl Start { - pub fn new() -> Start { - Start { - tag: Tag::unknown(), - filenames: vec![], - application: None, - } - } - - pub fn parse(&mut self, call_info: CallInfo) -> Result<(), ShellError> { - self.tag = call_info.name_tag.clone(); - self.parse_input_parameters(&call_info)?; - self.parse_application(&call_info); - Ok(()) - } - - fn add_filename(&mut self, filename: Tagged) -> Result<(), ShellError> { - if Path::new(&filename.item).exists() || url::Url::parse(&filename.item).is_ok() { - self.filenames.push(filename); - Ok(()) - } else { - Err(ShellError::labeled_error( - format!("The file '{}' does not exist", filename.item), - "doesn't exist", - filename.tag, - )) - } - } - - fn glob_to_values(&self, value: &Value) -> Result>, ShellError> { - let mut result = vec![]; - match nu_glob::glob(&value.as_string()?) { - Ok(paths) => { - for path_result in paths { - match path_result { - Ok(path) => result - .push(path.to_string_lossy().to_string().tagged(value.tag.clone())), - Err(glob_error) => { - return Err(ShellError::labeled_error( - glob_error.to_string(), - "glob error", - value.tag.clone(), - )); - } - } - } - } - Err(pattern_error) => { - return Err(ShellError::labeled_error( - pattern_error.to_string(), - "invalid pattern", - value.tag.clone(), - )) - } - } - - Ok(result) - } - - fn parse_input_parameters(&mut self, call_info: &CallInfo) -> Result<(), ShellError> { - let candidates = match &call_info.args.positional { - Some(values) => { - let mut result = vec![]; - - for value in values { - let val_str = value.as_string(); - match val_str { - Ok(s) => { - if s.to_ascii_lowercase().starts_with("http") - || s.to_ascii_lowercase().starts_with("https") - { - if webbrowser::open(&s).is_ok() { - result.push("http/web".to_string().tagged_unknown()) - } else { - return Err(ShellError::labeled_error( - &format!("error opening {}", &s), - "error opening url", - self.tag.span, - )); - } - } else { - let res = self.glob_to_values(value)?; - result.extend(res); - } - } - Err(e) => { - return Err(ShellError::labeled_error( - e.to_string(), - "no input given", - self.tag.span, - )); - } - } - } - - if result.is_empty() { - return Err(ShellError::labeled_error( - "No input given", - "no input given", - self.tag.span, - )); - } - result - } - None => { - return Err(ShellError::labeled_error( - "No input given", - "no input given", - self.tag.span, - )) - } - }; - - for candidate in candidates { - if !candidate.contains("http/web") { - self.add_filename(candidate)?; - } - } - - Ok(()) - } - - fn parse_application(&mut self, call_info: &CallInfo) { - self.application = if let Some(app) = call_info.args.get("application") { - match app.as_string() { - Ok(name) => Some(name), - Err(_) => None, - } - } else { - None - }; - } - - #[cfg(target_os = "macos")] - pub fn exec(&mut self) -> Result<(), ShellError> { - let mut args = vec![]; - args.append( - &mut self - .filenames - .iter() - .map(|x| x.item.clone()) - .collect::>(), - ); - - if let Some(app_name) = &self.application { - args.append(&mut vec![String::from("-a"), app_name.to_string()]); - } - exec_cmd("open", &args, self.tag.clone()) - } - - #[cfg(target_os = "windows")] - pub fn exec(&mut self) -> Result<(), ShellError> { - if let Some(app_name) = &self.application { - for file in &self.filenames { - match open::with(&file.item, app_name) { - Ok(_) => continue, - Err(_) => { - return Err(ShellError::labeled_error( - "Failed to open file with specified application", - "can't open with specified application", - file.tag.span, - )) - } - } - } - } else { - for file in &self.filenames { - match open::that(&file.item) { - Ok(_) => continue, - Err(_) => { - return Err(ShellError::labeled_error( - "Failed to open file with default application", - "can't open with default application", - file.tag.span, - )) - } - } - } - } - Ok(()) - } - - #[cfg(not(any(target_os = "windows", target_os = "macos")))] - pub fn exec(&mut self) -> Result<(), ShellError> { - let mut args = vec![]; - args.append( - &mut self - .filenames - .iter() - .map(|x| x.item.clone()) - .collect::>(), - ); - - if let Some(app_name) = &self.application { - exec_cmd(app_name, &args, self.tag.clone()) - } else { - for cmd in ["xdg-open", "gnome-open", "kde-open", "wslview"] { - if exec_cmd(cmd, &args, self.tag.clone()).is_err() { - continue; - } else { - return Ok(()); - } - } - Err(ShellError::labeled_error( - "Failed to open file(s) with xdg-open. gnome-open, kde-open, and wslview", - "failed to open xdg-open. gnome-open, kde-open, and wslview", - self.tag.span, - )) - } - } -} - -#[cfg(not(target_os = "windows"))] -fn exec_cmd(cmd: &str, args: &[String], tag: Tag) -> Result<(), ShellError> { - if args.is_empty() { - return Err(ShellError::labeled_error( - "No file(s) or application provided", - "no file(s) or application provided", - tag, - )); - } - let status = match Command::new(cmd) - .stdout(Stdio::null()) - .stderr(Stdio::null()) - .args(args) - .status() - { - Ok(exit_code) => exit_code, - Err(_) => { - return Err(ShellError::labeled_error( - "Failed to run native open syscall", - "failed to run native open call", - tag, - )) - } - }; - if status.success() { - Ok(()) - } else { - Err(ShellError::labeled_error( - "Failed to run start. Hint: The file(s)/application may not exist", - "failed to run", - tag, - )) - } -} diff --git a/crates/old/nu_plugin_to_bson/Cargo.toml b/crates/old/nu_plugin_to_bson/Cargo.toml deleted file mode 100644 index 61cf1f9231..0000000000 --- a/crates/old/nu_plugin_to_bson/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A converter plugin to the bson format for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_to_bson" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -bson = { version = "2.0.1", features = [ "chrono-0_4" ] } -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -num-traits = "0.2.14" - -[features] -dataframe = ["nu-protocol/dataframe"] - -[build-dependencies] diff --git a/crates/old/nu_plugin_to_bson/src/lib.rs b/crates/old/nu_plugin_to_bson/src/lib.rs deleted file mode 100644 index 9193d10c5e..0000000000 --- a/crates/old/nu_plugin_to_bson/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod nu; -mod to_bson; - -pub use to_bson::ToBson; diff --git a/crates/old/nu_plugin_to_bson/src/main.rs b/crates/old/nu_plugin_to_bson/src/main.rs deleted file mode 100644 index 47d3f0468c..0000000000 --- a/crates/old/nu_plugin_to_bson/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_to_bson::ToBson; - -fn main() { - serve_plugin(&mut ToBson::new()) -} diff --git a/crates/old/nu_plugin_to_bson/src/nu/mod.rs b/crates/old/nu_plugin_to_bson/src/nu/mod.rs deleted file mode 100644 index bf4c1b2535..0000000000 --- a/crates/old/nu_plugin_to_bson/src/nu/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::ToBson; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{ReturnValue, Signature, Value}; -use nu_source::Tag; - -impl Plugin for ToBson { - fn config(&mut self) -> Result { - Ok(Signature::build("to bson") - .usage("Convert table into .bson binary") - .filter()) - } - - fn filter(&mut self, input: Value) -> Result, ShellError> { - self.state.push(input); - Ok(vec![]) - } - - fn end_filter(&mut self) -> Result, ShellError> { - Ok(crate::to_bson::to_bson(self.state.clone(), Tag::unknown())) - } -} diff --git a/crates/old/nu_plugin_to_bson/src/nu/tests.rs b/crates/old/nu_plugin_to_bson/src/nu/tests.rs deleted file mode 100644 index d14c19bee3..0000000000 --- a/crates/old/nu_plugin_to_bson/src/nu/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod integration {} diff --git a/crates/old/nu_plugin_to_bson/src/to_bson.rs b/crates/old/nu_plugin_to_bson/src/to_bson.rs deleted file mode 100644 index b4bf79c5e7..0000000000 --- a/crates/old/nu_plugin_to_bson/src/to_bson.rs +++ /dev/null @@ -1,300 +0,0 @@ -use bson::{oid::ObjectId, spec::BinarySubtype, Bson, Document}; -use nu_errors::{CoerceInto, ShellError}; -use nu_protocol::{ - Dictionary, Primitive, ReturnSuccess, ReturnValue, SpannedTypeName, UnspannedPathMember, - UntaggedValue, Value, -}; -use nu_source::{Tag, TaggedItem}; -use num_traits::ToPrimitive; -use std::convert::TryInto; - -#[derive(Default)] -pub struct ToBson { - pub state: Vec, -} - -impl ToBson { - pub fn new() -> ToBson { - ToBson { state: vec![] } - } -} - -pub fn value_to_bson_value(v: &Value) -> Result { - Ok(match &v.value { - UntaggedValue::Primitive(Primitive::Boolean(b)) => Bson::Boolean(*b), - // FIXME: What about really big decimals? - UntaggedValue::Primitive(Primitive::Filesize(decimal)) => Bson::Double( - (decimal) - .to_f64() - .expect("Unimplemented BUG: What about big decimals?"), - ), - UntaggedValue::Primitive(Primitive::Duration(i)) => Bson::String(i.to_string()), - UntaggedValue::Primitive(Primitive::Date(d)) => { - Bson::DateTime(bson::DateTime::from_chrono(*d)) - } - UntaggedValue::Primitive(Primitive::EndOfStream) => Bson::Null, - UntaggedValue::Primitive(Primitive::BeginningOfStream) => Bson::Null, - UntaggedValue::Primitive(Primitive::Decimal(d)) => { - Bson::Double(d.to_f64().ok_or_else(|| { - ShellError::labeled_error( - "Could not convert value to decimal", - "could not convert to decimal", - &v.tag, - ) - })?) - } - UntaggedValue::Primitive(Primitive::Int(i)) => Bson::Int64(*i), - UntaggedValue::Primitive(Primitive::BigInt(i)) => { - Bson::Int64(i.tagged(&v.tag).coerce_into("converting to BSON")?) - } - UntaggedValue::Primitive(Primitive::Nothing) => Bson::Null, - UntaggedValue::Primitive(Primitive::String(s)) => Bson::String(s.clone()), - UntaggedValue::Primitive(Primitive::ColumnPath(path)) => Bson::Array( - path.iter() - .map(|x| match &x.unspanned { - UnspannedPathMember::String(string) => Ok(Bson::String(string.clone())), - UnspannedPathMember::Int(int) => Ok(Bson::Int64(*int)), - }) - .collect::, ShellError>>()?, - ), - UntaggedValue::Primitive(Primitive::GlobPattern(p)) => Bson::String(p.clone()), - UntaggedValue::Primitive(Primitive::FilePath(s)) => Bson::String(s.display().to_string()), - UntaggedValue::Table(l) => Bson::Array( - l.iter() - .map(value_to_bson_value) - .collect::>()?, - ), - UntaggedValue::Block(_) | UntaggedValue::Primitive(Primitive::Range(_)) => Bson::Null, - #[cfg(feature = "dataframe")] - UntaggedValue::DataFrame(_) | UntaggedValue::FrameStruct(_) => Bson::Null, - UntaggedValue::Error(e) => return Err(e.clone()), - UntaggedValue::Primitive(Primitive::Binary(b)) => Bson::Binary(bson::Binary { - subtype: BinarySubtype::Generic, - bytes: b.clone(), - }), - UntaggedValue::Row(o) => object_value_to_bson(o)?, - // TODO Impelmenting Bson::Undefined, Bson::MaxKey, Bson::MinKey and Bson::DbPointer - // These Variants weren't present in the previous version. - }) -} - -// object_value_to_bson handles all Objects, even those that correspond to special -// types (things like regex or javascript code). -fn object_value_to_bson(o: &Dictionary) -> Result { - let mut it = o.entries.iter(); - if it.len() > 2 { - return generic_object_value_to_bson(o); - } - match it.next() { - Some((regex, tagged_regex_value)) if regex == "$regex" => match it.next() { - Some((options, tagged_opts_value)) if options == "$options" => { - let r: Result = tagged_regex_value.try_into(); - let opts: Result = tagged_opts_value.try_into(); - match (r, opts) { - (Ok(pattern), Ok(options)) => { - Ok(Bson::RegularExpression(bson::Regex { pattern, options })) - } - _ => generic_object_value_to_bson(o), - } - } - _ => generic_object_value_to_bson(o), - }, - Some((javascript, tagged_javascript_value)) if javascript == "$javascript" => { - match it.next() { - Some((scope, tagged_scope_value)) if scope == "$scope" => { - let js: Result = tagged_javascript_value.try_into(); - let s: Result<&Dictionary, _> = tagged_scope_value.try_into(); - - match (js, s) { - (Ok(code), Ok(s)) => { - if let Bson::Document(scope) = object_value_to_bson(s)? { - Ok(Bson::JavaScriptCodeWithScope( - bson::JavaScriptCodeWithScope { code, scope }, - )) - } else { - generic_object_value_to_bson(o) - } - } - _ => generic_object_value_to_bson(o), - } - } - None => { - let js: Result = tagged_javascript_value.try_into(); - - match js { - Err(_) => generic_object_value_to_bson(o), - Ok(v) => Ok(Bson::JavaScriptCode(v)), - } - } - _ => generic_object_value_to_bson(o), - } - } - Some((timestamp, tagged_timestamp_value)) if timestamp == "$timestamp" => { - let ts: Result = tagged_timestamp_value.try_into(); - if let Ok(time) = ts { - Ok(Bson::Timestamp(bson::Timestamp { - time: time as u32, - increment: Default::default(), - })) - } else { - generic_object_value_to_bson(o) - } - } - Some((binary_subtype, tagged_binary_subtype_value)) - if binary_subtype == "$binary_subtype" => - { - match it.next() { - Some((binary, tagged_bin_value)) if binary == "$binary" => { - let bst = get_binary_subtype(tagged_binary_subtype_value); - let bin: Result, _> = tagged_bin_value.try_into(); - - match (bin, bst) { - (Ok(bin), Ok(subtype)) => Ok(Bson::Binary(bson::Binary { - subtype, - bytes: bin, - })), - _ => generic_object_value_to_bson(o), - } - } - _ => generic_object_value_to_bson(o), - } - } - Some((object_id, tagged_object_id_value)) if object_id == "$object_id" => { - let obj_id: Result = tagged_object_id_value.try_into(); - - if let Ok(obj_id) = obj_id { - let obj_id = ObjectId::parse_str(&obj_id); - - if let Ok(obj_id) = obj_id { - Ok(Bson::ObjectId(obj_id)) - } else { - generic_object_value_to_bson(o) - } - } else { - generic_object_value_to_bson(o) - } - } - Some((symbol, tagged_symbol_value)) if symbol == "$symbol" => { - let sym: Result = tagged_symbol_value.try_into(); - if let Ok(sym) = sym { - Ok(Bson::Symbol(sym)) - } else { - generic_object_value_to_bson(o) - } - } - _ => generic_object_value_to_bson(o), - } -} - -fn get_binary_subtype(tagged_value: &Value) -> Result { - match &tagged_value.value { - UntaggedValue::Primitive(Primitive::String(s)) => Ok(match s.as_ref() { - "generic" => BinarySubtype::Generic, - "function" => BinarySubtype::Function, - "binary_old" => BinarySubtype::BinaryOld, - "uuid_old" => BinarySubtype::UuidOld, - "uuid" => BinarySubtype::Uuid, - "md5" => BinarySubtype::Md5, - _ => unreachable!(), - }), - UntaggedValue::Primitive(Primitive::BigInt(i)) => Ok(BinarySubtype::UserDefined( - i.tagged(&tagged_value.tag) - .coerce_into("converting to BSON binary subtype")?, - )), - _ => Err(ShellError::type_error( - "bson binary", - tagged_value.spanned_type_name(), - )), - } -} - -// generic_object_value_bson handles any Object that does not -// correspond to a special bson type (things like regex or javascript code). -fn generic_object_value_to_bson(o: &Dictionary) -> Result { - let mut doc = Document::new(); - for (k, v) in &o.entries { - doc.insert(k.clone(), value_to_bson_value(v)?); - } - Ok(Bson::Document(doc)) -} - -fn shell_encode_document(writer: &mut Vec, doc: Document, tag: Tag) -> Result<(), ShellError> { - match doc.to_writer(writer) { - Err(e) => Err(ShellError::labeled_error( - format!("Failed to encode document due to: {:?}", e), - "requires BSON-compatible document", - tag, - )), - _ => Ok(()), - } -} - -fn bson_value_to_bytes(bson: Bson, tag: Tag) -> Result, ShellError> { - let mut out = Vec::new(); - match bson { - Bson::Array(a) => { - for v in a { - match v { - Bson::Document(d) => shell_encode_document(&mut out, d, tag.clone())?, - _ => { - return Err(ShellError::labeled_error( - format!("All top level values must be Documents, got {:?}", v), - "requires BSON-compatible document", - &tag, - )) - } - } - } - } - Bson::Document(d) => shell_encode_document(&mut out, d, tag)?, - _ => { - return Err(ShellError::labeled_error( - format!("All top level values must be Documents, got {:?}", bson), - "requires BSON-compatible document", - tag, - )) - } - } - Ok(out) -} - -pub fn to_bson(input: Vec, name_tag: Tag) -> Vec { - let name_span = name_tag.span; - - let to_process_input = match input.len() { - x if x > 1 => { - let tag = input[0].tag.clone(); - vec![Value { - value: UntaggedValue::Table(input), - tag, - }] - } - 1 => input, - _ => vec![], - }; - - to_process_input - .into_iter() - .map(move |value| match value_to_bson_value(&value) { - Ok(bson_value) => { - let value_span = value.tag.span; - - match bson_value_to_bytes(bson_value, name_tag.clone()) { - Ok(x) => ReturnSuccess::value(UntaggedValue::binary(x).into_value(name_span)), - _ => Err(ShellError::labeled_error_with_secondary( - "Expected a table with BSON-compatible structure from pipeline", - "requires BSON-compatible input", - name_span, - "originates from here".to_string(), - value_span, - )), - } - } - _ => Err(ShellError::labeled_error( - "Expected a table with BSON-compatible structure from pipeline", - "requires BSON-compatible input", - &name_tag, - )), - }) - .collect() -} diff --git a/crates/old/nu_plugin_to_sqlite/Cargo.toml b/crates/old/nu_plugin_to_sqlite/Cargo.toml deleted file mode 100644 index bbb28f686a..0000000000 --- a/crates/old/nu_plugin_to_sqlite/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "A converter plugin to the SQLite format for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_to_sqlite" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -hex = "0.4.2" -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -nu-source = { path="../nu-source", version = "0.73.1" } -tempfile = "3.2.0" - -[dependencies.rusqlite] -features = ["bundled", "blob"] -version = "0.26.1" - -[build-dependencies] diff --git a/crates/old/nu_plugin_to_sqlite/src/lib.rs b/crates/old/nu_plugin_to_sqlite/src/lib.rs deleted file mode 100644 index 3e814f55b7..0000000000 --- a/crates/old/nu_plugin_to_sqlite/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod nu; -mod to_sqlite; - -pub use to_sqlite::ToSqlite; diff --git a/crates/old/nu_plugin_to_sqlite/src/main.rs b/crates/old/nu_plugin_to_sqlite/src/main.rs deleted file mode 100644 index 5f69232256..0000000000 --- a/crates/old/nu_plugin_to_sqlite/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_to_sqlite::ToSqlite; - -fn main() { - serve_plugin(&mut ToSqlite::new()) -} diff --git a/crates/old/nu_plugin_to_sqlite/src/nu/mod.rs b/crates/old/nu_plugin_to_sqlite/src/nu/mod.rs deleted file mode 100644 index 22670e437a..0000000000 --- a/crates/old/nu_plugin_to_sqlite/src/nu/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::ToSqlite; -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{ReturnValue, Signature, Value}; -use nu_source::Tag; - -impl Plugin for ToSqlite { - fn config(&mut self) -> Result { - Ok(Signature::build("to sqlite") - .usage("Convert table into sqlite binary") - .filter()) - } - - fn filter(&mut self, input: Value) -> Result, ShellError> { - self.state.push(input); - Ok(vec![]) - } - - fn end_filter(&mut self) -> Result, ShellError> { - crate::to_sqlite::to_sqlite(self.state.clone(), Tag::unknown()) - } -} diff --git a/crates/old/nu_plugin_to_sqlite/src/nu/tests.rs b/crates/old/nu_plugin_to_sqlite/src/nu/tests.rs deleted file mode 100644 index d14c19bee3..0000000000 --- a/crates/old/nu_plugin_to_sqlite/src/nu/tests.rs +++ /dev/null @@ -1 +0,0 @@ -mod integration {} diff --git a/crates/old/nu_plugin_to_sqlite/src/to_sqlite.rs b/crates/old/nu_plugin_to_sqlite/src/to_sqlite.rs deleted file mode 100644 index 69466338c9..0000000000 --- a/crates/old/nu_plugin_to_sqlite/src/to_sqlite.rs +++ /dev/null @@ -1,172 +0,0 @@ -use hex::encode; -use nu_errors::ShellError; -use nu_protocol::{Dictionary, Primitive, ReturnSuccess, ReturnValue, UntaggedValue, Value}; -use nu_source::Tag; -use rusqlite::Connection; -use std::io::Read; - -#[derive(Default)] -pub struct ToSqlite { - pub state: Vec, -} - -impl ToSqlite { - pub fn new() -> ToSqlite { - ToSqlite { state: vec![] } - } -} -fn comma_concat(acc: String, current: String) -> String { - if acc.is_empty() { - current - } else { - format!("{}, {}", acc, current) - } -} - -fn get_columns(rows: &[Value]) -> Result { - match &rows[0].value { - UntaggedValue::Row(d) => Ok(d - .entries - .iter() - .map(|(k, _v)| k.clone()) - .fold("".to_string(), comma_concat)), - _ => Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Could not find table column names", - )), - } -} - -fn nu_value_to_sqlite_string(v: Value) -> String { - match &v.value { - UntaggedValue::Primitive(p) => match p { - Primitive::Nothing => "NULL".into(), - Primitive::BigInt(i) => i.to_string(), - Primitive::Int(i) => i.to_string(), - Primitive::Duration(i) => i.to_string(), - Primitive::Decimal(f) => f.to_string(), - Primitive::Filesize(u) => u.to_string(), - Primitive::GlobPattern(s) => format!("'{}'", s.replace("'", "''")), - Primitive::String(s) => format!("'{}'", s.replace("'", "''")), - Primitive::Boolean(true) => "1".into(), - Primitive::Boolean(_) => "0".into(), - Primitive::Date(d) => format!("'{}'", d), - Primitive::FilePath(p) => format!("'{}'", p.display().to_string().replace("'", "''")), - Primitive::Binary(u) => format!("x'{}'", encode(u)), - Primitive::BeginningOfStream - | Primitive::EndOfStream - | Primitive::ColumnPath(_) - | Primitive::Range(_) => "NULL".into(), - }, - _ => "NULL".into(), - } -} - -fn get_insert_values(rows: Vec) -> Result { - let values: Result, _> = rows - .into_iter() - .map(|value| match value.value { - UntaggedValue::Row(d) => Ok(format!( - "({})", - d.entries - .iter() - .map(|(_k, v)| nu_value_to_sqlite_string(v.clone())) - .fold("".to_string(), comma_concat) - )), - _ => Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Could not find table column names", - )), - }) - .collect(); - let values = values?; - Ok(values.join(", ")) -} - -fn generate_statements(table: Dictionary) -> Result<(String, String), std::io::Error> { - let table_name = match table.entries.get("table_name") { - Some(Value { - value: UntaggedValue::Primitive(Primitive::String(table_name)), - .. - }) => table_name, - _ => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Could not find table name", - )) - } - }; - let (columns, insert_values) = match table.entries.get("table_values") { - Some(Value { - value: UntaggedValue::Table(l), - .. - }) => { - if l.is_empty() { - return Ok((String::new(), String::new())); - } - (get_columns(l), get_insert_values(l.to_vec())) - } - _ => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Could not find table values", - )) - } - }; - - let create = format!("create table {}({})", table_name, columns?); - let insert = format!("insert into {} values {}", table_name, insert_values?); - Ok((create, insert)) -} - -fn sqlite_input_stream_to_bytes(values: Vec) -> Result { - // FIXME: should probably write a sqlite virtual filesystem - // that will allow us to use bytes as a file to avoid this - // write out, but this will require C code. Might be - // best done as a PR to rusqlite. - let mut tempfile = tempfile::NamedTempFile::new()?; - let conn = match Connection::open(tempfile.path()) { - Ok(conn) => conn, - Err(e) => return Err(std::io::Error::new(std::io::ErrorKind::Other, e)), - }; - let tag = values[0].tag.clone(); - for value in values { - match &value.value { - UntaggedValue::Row(d) => { - let (create, insert) = generate_statements(d.to_owned())?; - if create.is_empty() { - continue; - } - match conn - .execute(&create, []) - .and_then(|_| conn.execute(&insert, [])) - { - Ok(_) => (), - Err(e) => { - return Err(std::io::Error::new(std::io::ErrorKind::Other, e)); - } - } - } - other => { - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - format!("Expected row, found {:?}", other), - )) - } - } - } - let mut out = Vec::new(); - tempfile.read_to_end(&mut out)?; - Ok(UntaggedValue::binary(out).into_value(tag)) -} - -pub fn to_sqlite(input: Vec, name_tag: Tag) -> Result, ShellError> { - match sqlite_input_stream_to_bytes(input) { - Ok(out) => Ok(vec![ReturnSuccess::value(out)]), - _ => Err(ShellError::labeled_error( - "Expected a table with SQLite-compatible structure from pipeline", - "requires SQLite-compatible input", - name_tag, - )), - } -} diff --git a/crates/old/nu_plugin_tree/Cargo.toml b/crates/old/nu_plugin_tree/Cargo.toml deleted file mode 100644 index ed812d6269..0000000000 --- a/crates/old/nu_plugin_tree/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -authors = ["The Nushell Project Developers"] -description = "Tree viewer plugin for Nushell" -edition = "2018" -license = "MIT" -name = "nu_plugin_tree" -version = "0.73.1" - -[lib] -doctest = false - -[dependencies] -derive-new = "0.5.8" -nu-errors = { path="../nu-errors", version = "0.73.1" } -nu-plugin = { path="../nu-plugin", version = "0.73.1" } -nu-protocol = { path="../nu-protocol", version = "0.73.1" } -ptree = { version = "0.4.0", default-features = false } - - -[build-dependencies] diff --git a/crates/old/nu_plugin_tree/src/lib.rs b/crates/old/nu_plugin_tree/src/lib.rs deleted file mode 100644 index d71f024ce6..0000000000 --- a/crates/old/nu_plugin_tree/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -mod nu; -mod tree; - -pub use tree::TreeViewer; diff --git a/crates/old/nu_plugin_tree/src/main.rs b/crates/old/nu_plugin_tree/src/main.rs deleted file mode 100644 index 7ba6d9ea58..0000000000 --- a/crates/old/nu_plugin_tree/src/main.rs +++ /dev/null @@ -1,6 +0,0 @@ -use nu_plugin::serve_plugin; -use nu_plugin_tree::TreeViewer; - -fn main() { - serve_plugin(&mut TreeViewer); -} diff --git a/crates/old/nu_plugin_tree/src/nu/mod.rs b/crates/old/nu_plugin_tree/src/nu/mod.rs deleted file mode 100644 index 3dda837892..0000000000 --- a/crates/old/nu_plugin_tree/src/nu/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use nu_errors::ShellError; -use nu_plugin::Plugin; -use nu_protocol::{CallInfo, Signature, Value}; - -use crate::tree::TreeView; -use crate::TreeViewer; - -impl Plugin for TreeViewer { - fn config(&mut self) -> Result { - Ok(Signature::build("tree").usage("View the contents of the pipeline as a tree.")) - } - - fn sink(&mut self, _call_info: CallInfo, input: Vec) { - for i in &input { - let view = TreeView::from_value(i); - let _ = view.render_view(); - } - } -} diff --git a/crates/old/nu_plugin_tree/src/tree.rs b/crates/old/nu_plugin_tree/src/tree.rs deleted file mode 100644 index 7a84f8cad1..0000000000 --- a/crates/old/nu_plugin_tree/src/tree.rs +++ /dev/null @@ -1,80 +0,0 @@ -use derive_new::new; -use nu_errors::ShellError; -use nu_protocol::{format_primitive, UntaggedValue, Value}; -use ptree::item::StringItem; -use ptree::output::print_tree_with; -use ptree::print_config::PrintConfig; -use ptree::style::{Color, Style}; -use ptree::TreeBuilder; - -pub struct TreeViewer; -#[derive(new)] -pub struct TreeView { - tree: StringItem, -} - -impl TreeView { - fn from_value_helper(value: &UntaggedValue, mut builder: &mut TreeBuilder) { - match value { - UntaggedValue::Primitive(p) => { - let _ = builder.add_empty_child(format_primitive(p, None)); - } - UntaggedValue::Row(o) => { - for (k, v) in &o.entries { - builder = builder.begin_child(k.clone()); - Self::from_value_helper(v, builder); - builder = builder.end_child(); - } - } - UntaggedValue::Table(l) => { - for elem in l { - Self::from_value_helper(elem, builder); - } - } - _ => {} - } - } - - pub fn from_value(value: &Value) -> TreeView { - let descs = value.data_descriptors(); - - let mut tree = TreeBuilder::new("".to_string()); - let mut builder = &mut tree; - - for desc in descs { - let value = match &value.value { - UntaggedValue::Row(d) => d.get_data(&desc).borrow().clone(), - _ => value.clone(), - }; - builder = builder.begin_child(desc.clone()); - Self::from_value_helper(&value, builder); - builder = builder.end_child(); - //entries.push((desc.name.clone(), value.borrow().copy())) - } - - TreeView::new(builder.build()) - } - - pub fn render_view(&self) -> Result<(), ShellError> { - // Set up the print configuration - let config = { - let mut config = PrintConfig::from_env(); - config.branch = Style { - foreground: Some(Color::Green), - dimmed: true, - ..Style::default() - }; - config.leaf = Style { - bold: true, - ..Style::default() - }; - config.indent = 4; - config - }; - - // Print out the tree using custom formatting - print_tree_with(&self.tree, &config)?; - - Ok(()) - } -}