Skip to main content

nu_command/formats/from/
nuon.rs

1use nu_engine::command_prelude::*;
2use nu_protocol::shell_error::generic::GenericError;
3
4#[derive(Clone)]
5pub struct FromNuon;
6
7impl Command for FromNuon {
8    fn name(&self) -> &str {
9        "from nuon"
10    }
11
12    fn description(&self) -> &str {
13        "Convert from nuon to structured data."
14    }
15
16    fn signature(&self) -> nu_protocol::Signature {
17        Signature::build("from nuon")
18            .input_output_types(vec![(Type::String, Type::Any)])
19            .category(Category::Formats)
20    }
21
22    fn examples(&self) -> Vec<Example<'_>> {
23        vec![
24            Example {
25                example: "'{ a:1 }' | from nuon",
26                description: "Converts nuon formatted string to table.",
27                result: Some(Value::test_record(record! {
28                    "a" => Value::test_int(1),
29                })),
30            },
31            Example {
32                example: "'{ a:1, b: [1, 2] }' | from nuon",
33                description: "Converts nuon formatted string to table.",
34                result: Some(Value::test_record(record! {
35                    "a" => Value::test_int(1),
36                    "b" => Value::test_list(vec![Value::test_int(1), Value::test_int(2)]),
37                })),
38            },
39            Example {
40                example: "'{a:1,b:[1,2]}' | from nuon",
41                description: "Converts raw nuon formatted string to table.",
42                result: Some(Value::test_record(record! {
43                    "a" => Value::test_int(1),
44                    "b" => Value::test_list(vec![Value::test_int(1), Value::test_int(2)]),
45                })),
46            },
47        ]
48    }
49
50    fn run(
51        &self,
52        _engine_state: &EngineState,
53        _stack: &mut Stack,
54        call: &Call,
55        input: PipelineData,
56    ) -> Result<PipelineData, ShellError> {
57        let head = call.head;
58        let (string_input, _span, metadata) = input.collect_string_strict(head)?;
59
60        match nuon::from_nuon(&string_input, Some(head)) {
61            Ok(result) => Ok(result
62                .into_pipeline_data_with_metadata(metadata.map(|md| md.with_content_type(None)))),
63            Err(err) => Err(ShellError::Generic(
64                GenericError::new(
65                    "error when loading nuon text",
66                    "could not load nuon text",
67                    head,
68                )
69                .with_inner([err]),
70            )),
71        }
72    }
73}
74
75#[cfg(test)]
76mod test {
77    use nu_cmd_lang::eval_pipeline_without_terminal_expression;
78
79    use crate::Reject;
80    use crate::{Metadata, MetadataSet};
81
82    use super::*;
83
84    #[test]
85    fn test_examples() -> nu_test_support::Result {
86        nu_test_support::test().examples(FromNuon)
87    }
88
89    #[test]
90    fn test_content_type_metadata() {
91        let mut engine_state = Box::new(EngineState::new());
92        let delta = {
93            let mut working_set = StateWorkingSet::new(&engine_state);
94
95            working_set.add_decl(Box::new(FromNuon {}));
96            working_set.add_decl(Box::new(Metadata {}));
97            working_set.add_decl(Box::new(MetadataSet {}));
98            working_set.add_decl(Box::new(Reject {}));
99
100            working_set.render()
101        };
102
103        engine_state
104            .merge_delta(delta)
105            .expect("Error merging delta");
106
107        let cmd = "'[[a, b]; [1, 2]]' | metadata set --content-type 'application/x-nuon' --path-columns [name] | from nuon | metadata | reject span | $in";
108        let result = eval_pipeline_without_terminal_expression(
109            cmd,
110            std::env::temp_dir().as_ref(),
111            &mut engine_state,
112        );
113        assert_eq!(
114            Value::test_record(
115                record!("path_columns" => Value::test_list(vec![Value::test_string("name")]))
116            ),
117            result.expect("There should be a result")
118        )
119    }
120}