mirror of
https://github.com/nushell/nushell.git
synced 2025-05-06 19:14:25 +02:00
To toml fix (#7597)
# Description Fixes #7510 . Remove support for tables from `to toml` command and update description. Previously, as indicated in #7510 , a table could be converted to toml and would result in this invalid toml:  This commit removes functionality of serializing tables and now `to toml` produces an error:  The `from toml` command already acknowledges the fact that toml can contain only records as indicated in its signature  Now help of `to toml` reflects this feature of format as well:  Additionally new tests were created for `to toml` command. See `crates\nu-command\tests\format_conversions\toml.rs`. Also removed undocumented behavior that would accept and validate a string as toml:  # User-Facing Changes - Serializing tables to toml now produces error instead of invalid toml - Updated `to toml` help - Remove undocumented "validation" (not really user-facing) # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - [x] `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - [x] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - [x] `cargo test --workspace` to check that all tests pass # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date.
This commit is contained in:
parent
9ffa3e55c2
commit
ddc00014be
@ -14,19 +14,19 @@ impl Command for ToToml {
|
|||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("to toml")
|
Signature::build("to toml")
|
||||||
.input_output_types(vec![(Type::Any, Type::String)])
|
.input_output_types(vec![(Type::Record(vec![]), Type::String)])
|
||||||
.category(Category::Formats)
|
.category(Category::Formats)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
"Convert table into .toml text"
|
"Convert record into .toml text"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
vec![Example {
|
vec![Example {
|
||||||
description: "Outputs an TOML string representing the contents of this table",
|
description: "Outputs an TOML string representing the contents of this record",
|
||||||
example: r#"[[foo bar]; ["1" "2"]] | to toml"#,
|
example: r#"{foo: 1 bar: 'qwe'} | to toml"#,
|
||||||
result: Some(Value::test_string("bar = \"2\"\nfoo = \"1\"\n")),
|
result: Some(Value::test_string("bar = \"qwe\"\nfoo = 1\n")),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,26 +127,6 @@ fn value_to_toml_value(
|
|||||||
) -> Result<toml::Value, ShellError> {
|
) -> Result<toml::Value, ShellError> {
|
||||||
match v {
|
match v {
|
||||||
Value::Record { .. } => helper(engine_state, v),
|
Value::Record { .. } => helper(engine_state, v),
|
||||||
Value::List { ref vals, span } => match &vals[..] {
|
|
||||||
[Value::Record { .. }, _end @ ..] => helper(engine_state, v),
|
|
||||||
_ => Err(ShellError::UnsupportedInput(
|
|
||||||
"Expected a table with TOML-compatible structure".to_string(),
|
|
||||||
"value originates from here".into(),
|
|
||||||
head,
|
|
||||||
*span,
|
|
||||||
)),
|
|
||||||
},
|
|
||||||
Value::String { val, span } => {
|
|
||||||
// Attempt to de-serialize the String
|
|
||||||
toml::de::from_str(val).map_err(|_| {
|
|
||||||
ShellError::UnsupportedInput(
|
|
||||||
"unable to de-serialize string to TOML".into(),
|
|
||||||
format!("input: '{:?}'", val),
|
|
||||||
head,
|
|
||||||
*span,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// Propagate existing errors
|
// Propagate existing errors
|
||||||
Value::Error { error } => Err(error.clone()),
|
Value::Error { error } => Err(error.clone()),
|
||||||
_ => Err(ShellError::UnsupportedInput(
|
_ => Err(ShellError::UnsupportedInput(
|
||||||
@ -225,30 +205,6 @@ mod tests {
|
|||||||
toml::Value::String("array".to_owned())
|
toml::Value::String("array".to_owned())
|
||||||
]))
|
]))
|
||||||
);
|
);
|
||||||
// TOML string
|
|
||||||
let tv = value_to_toml_value(
|
|
||||||
&engine_state,
|
|
||||||
&Value::test_string(
|
|
||||||
r#"
|
|
||||||
title = "TOML Example"
|
|
||||||
|
|
||||||
[owner]
|
|
||||||
name = "Tom Preston-Werner"
|
|
||||||
dob = 1979-05-27T07:32:00-08:00 # First class dates
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rustyline = "4.1.0"
|
|
||||||
sysinfo = "0.8.4"
|
|
||||||
chrono = { version = "0.4.23", features = ["serde"] }
|
|
||||||
"#,
|
|
||||||
),
|
|
||||||
Span::test_data(),
|
|
||||||
)
|
|
||||||
.expect("Expected Ok from valid TOML string");
|
|
||||||
assert_eq!(
|
|
||||||
tv.get("title").unwrap(),
|
|
||||||
&toml::Value::String("TOML Example".to_owned())
|
|
||||||
);
|
|
||||||
//
|
//
|
||||||
// Negative Tests
|
// Negative Tests
|
||||||
//
|
//
|
||||||
|
@ -1,7 +1,93 @@
|
|||||||
use nu_test_support::{nu, pipeline};
|
use nu_test_support::{nu, pipeline};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn table_to_toml_text_and_from_toml_text_back_into_table() {
|
fn record_map_to_toml() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
{a: 1 b: 2 c: 'qwe'}
|
||||||
|
| to toml
|
||||||
|
| from toml
|
||||||
|
| $in == {a: 1 b: 2 c: 'qwe'}
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested_records_to_toml() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
{a: {a: a b: b} c: 1}
|
||||||
|
| to toml
|
||||||
|
| from toml
|
||||||
|
| $in == {a: {a: a b: b} c: 1}
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn records_with_tables_to_toml() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
{a: [[a b]; [1 2] [3 4]] b: [[c d e]; [1 2 3]]}
|
||||||
|
| to toml
|
||||||
|
| from toml
|
||||||
|
| $in == {a: [[a b]; [1 2] [3 4]] b: [[c d e]; [1 2 3]]}
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn nested_tables_to_toml() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
{c: [[f g]; [[[h k]; [1 2] [3 4]] 1]]}
|
||||||
|
| to toml
|
||||||
|
| from toml
|
||||||
|
| $in == {c: [[f g]; [[[h k]; [1 2] [3 4]] 1]]}
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn table_to_toml_fails() {
|
||||||
|
// Tables cant be represented in toml
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
try { [[a b]; [1 2] [5 6]] | to toml | false } catch { true }
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn string_to_toml_fails() {
|
||||||
|
// Strings are not a top-level toml structure
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
try { 'not a valid toml' | to toml | false } catch { true }
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn big_record_to_toml_text_and_from_toml_text_back_into_record() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
cwd: "tests/fixtures/formats", pipeline(
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
r#"
|
r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user