nu_command/formats/from/
nuon.rs1use 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}