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:


![image](https://user-images.githubusercontent.com/17511668/209443930-c3dd3a3f-5ffd-4273-9c10-acbb345c788e.png)

This commit removes functionality of serializing tables and now `to
toml` produces an error:


![image](https://user-images.githubusercontent.com/17511668/209443975-be119465-8946-4644-8994-489ca94f6006.png)

The `from toml` command already acknowledges the fact that toml can
contain only records as indicated in its signature


![image](https://user-images.githubusercontent.com/17511668/209443995-1590d044-a790-4be3-a967-b26292a6e70c.png)

Now help of `to toml` reflects this feature of format as well:


![image](https://user-images.githubusercontent.com/17511668/209444014-7cfe8f8e-ad8a-4845-a151-24df6b99a1a2.png)

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:


![image](https://user-images.githubusercontent.com/17511668/209449482-5d876074-fc5b-4b21-b8a5-64e643a50083.png)


# 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:
Artemiy 2022-12-25 00:12:09 +03:00 committed by GitHub
parent 9ffa3e55c2
commit ddc00014be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 50 deletions

View File

@ -14,19 +14,19 @@ impl Command for ToToml {
fn signature(&self) -> Signature {
Signature::build("to toml")
.input_output_types(vec![(Type::Any, Type::String)])
.input_output_types(vec![(Type::Record(vec![]), Type::String)])
.category(Category::Formats)
}
fn usage(&self) -> &str {
"Convert table into .toml text"
"Convert record into .toml text"
}
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Outputs an TOML string representing the contents of this table",
example: r#"[[foo bar]; ["1" "2"]] | to toml"#,
result: Some(Value::test_string("bar = \"2\"\nfoo = \"1\"\n")),
description: "Outputs an TOML string representing the contents of this record",
example: r#"{foo: 1 bar: 'qwe'} | to toml"#,
result: Some(Value::test_string("bar = \"qwe\"\nfoo = 1\n")),
}]
}
@ -127,26 +127,6 @@ fn value_to_toml_value(
) -> Result<toml::Value, ShellError> {
match 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
Value::Error { error } => Err(error.clone()),
_ => Err(ShellError::UnsupportedInput(
@ -225,30 +205,6 @@ mod tests {
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
//

View File

@ -1,7 +1,93 @@
use nu_test_support::{nu, pipeline};
#[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!(
cwd: "tests/fixtures/formats", pipeline(
r#"