Skip to main content

xs/nu/commands/
import_command.rs

1use nu_protocol::engine::{Call, Command, EngineState, Stack};
2use nu_protocol::shell_error::generic::GenericError;
3use nu_protocol::{Category, PipelineData, ShellError, Signature, Type};
4
5use crate::nu::util;
6use crate::store::{Frame, Store};
7
8#[derive(Clone)]
9pub struct ImportCommand {
10    store: Store,
11}
12
13impl ImportCommand {
14    pub fn new(store: Store) -> Self {
15        Self { store }
16    }
17}
18
19impl Command for ImportCommand {
20    fn name(&self) -> &str {
21        ".import"
22    }
23
24    fn signature(&self) -> Signature {
25        Signature::build(".import")
26            .input_output_types(vec![(Type::Any, Type::Any)])
27            .category(Category::Experimental)
28    }
29
30    fn description(&self) -> &str {
31        "Insert a frame verbatim into the store, preserving its id. The counterpart to export: pipe in a frame record (or its JSON) to restore it."
32    }
33
34    fn run(
35        &self,
36        _engine_state: &EngineState,
37        _stack: &mut Stack,
38        call: &Call,
39        input: PipelineData,
40    ) -> Result<PipelineData, ShellError> {
41        let value = input.into_value(call.head)?;
42
43        // Accept either a JSON string (a line from frames.jsonl) or a record.
44        let frame: Frame = match &value {
45            nu_protocol::Value::String { val, .. } => serde_json::from_str(val),
46            other => serde_json::from_value(util::value_to_json(other)),
47        }
48        .map_err(|e| {
49            ShellError::Generic(GenericError::new(
50                "Invalid frame",
51                format!("Could not read a frame from the input: {e}"),
52                call.head,
53            ))
54        })?;
55
56        self.store.insert_frame(&frame).map_err(|e| {
57            ShellError::Generic(GenericError::new(
58                "Failed to import frame",
59                e.to_string(),
60                call.head,
61            ))
62        })?;
63
64        Ok(PipelineData::Value(
65            util::frame_to_value(&frame, call.head, false),
66            None,
67        ))
68    }
69}