use serde::Deserialize;
use snapbox::assert_data_eq;
use snapbox::prelude::*;
use snapbox::str;
#[derive(Debug, Deserialize, PartialEq)]
struct OuterStruct {
inner: TheEnum,
}
#[derive(Debug, Deserialize, PartialEq)]
enum TheEnum {
Plain,
Tuple(i64, bool),
NewType(String),
Struct { value: i64 },
}
#[derive(Debug, Deserialize, PartialEq)]
struct Val {
val: TheEnum,
}
#[derive(Debug, Deserialize, PartialEq)]
struct Multi {
enums: Vec<TheEnum>,
}
#[test]
fn invalid_variant_returns_error_with_good_message_string() {
let input = "\"NonExistent\"";
let expected = str![[r#"
unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
"#]]
.raw();
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
let input = "val = \"NonExistent\"";
let expected = str![[r#"
TOML parse error at line 1, column 7
|
1 | val = "NonExistent"
| ^^^^^^^^^^^^^
unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
"#]]
.raw();
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
}
#[test]
fn invalid_variant_returns_error_with_good_message_inline_table() {
let input = "{ NonExistent = {} }";
let expected = str![[r#"
unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
"#]]
.raw();
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
let input = "val = { NonExistent = {} }";
let expected = str![[r#"
TOML parse error at line 1, column 9
|
1 | val = { NonExistent = {} }
| ^^^^^^^^^^^
unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
"#]]
.raw();
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
}
#[test]
fn extra_field_returns_expected_empty_table_error() {
let input = "{ Plain = { extra_field = 404 } }";
let expected = str![[r#"
expected empty table
"#]]
.raw();
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
let input = "val = { Plain = { extra_field = 404 } }";
let expected = str![[r#"
TOML parse error at line 1, column 17
|
1 | val = { Plain = { extra_field = 404 } }
| ^^^^^^^^^^^^^^^^^^^^^
expected empty table
"#]]
.raw();
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
}
#[test]
fn extra_field_returns_expected_empty_table_error_struct_variant() {
let input = "{ Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }";
let expected = str![[r#"
unexpected keys in table: extra_0, extra_1, available keys: value
"#]]
.raw();
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
let input = "val = { Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }";
let expected = str![[r#"
TOML parse error at line 1, column 33
|
1 | val = { Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }
| ^^^^^^^
unexpected keys in table: extra_0, extra_1, available keys: value
"#]]
.raw();
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap_err().to_string(), expected);
}
mod enum_unit {
use super::*;
#[test]
fn from_str() {
let input = "\"Plain\"";
let expected = str![[r#"
Plain
"#]];
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
let input = "val = \"Plain\"";
let expected = str![[r#"
Val {
val: Plain,
}
"#]];
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_inline_table() {
let input = "{ Plain = {} }";
let expected = str![[r#"
Plain
"#]];
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
let input = "val = { Plain = {} }";
let expected = str![[r#"
Val {
val: Plain,
}
"#]];
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_std_table() {
let input = "[Plain]";
let expected = str![[r#"
Plain
"#]];
let result = crate::from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
}
mod enum_tuple {
use super::*;
#[test]
fn from_inline_table() {
let input = "{ Tuple = { 0 = -123, 1 = true } }";
let expected = str![[r#"
Tuple(
-123,
true,
)
"#]];
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
let input = "val = { Tuple = { 0 = -123, 1 = true } }";
let expected = str![[r#"
Val {
val: Tuple(
-123,
true,
),
}
"#]];
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_std_table() {
let input = r#"[Tuple]
0 = -123
1 = true
"#;
let expected = str![[r#"
Tuple(
-123,
true,
)
"#]];
let result = crate::from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
}
mod enum_newtype {
use super::*;
#[test]
fn from_inline_table() {
let input = r#"{ NewType = "value" }"#;
let expected = str![[r#"
NewType(
"value",
)
"#]];
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
let input = r#"val = { NewType = "value" }"#;
let expected = str![[r#"
Val {
val: NewType(
"value",
),
}
"#]];
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_std_table() {
assert_eq!(
TheEnum::NewType("value".to_owned()),
crate::from_str(r#"NewType = "value""#).unwrap()
);
assert_eq!(
Val {
val: TheEnum::NewType("value".to_owned()),
},
crate::from_str(
r#"[val]
NewType = "value"
"#
)
.unwrap()
);
}
}
mod enum_struct {
use super::*;
#[test]
fn from_inline_table() {
let input = "{ Struct = { value = -123 } }";
let expected = str![[r#"
Struct {
value: -123,
}
"#]];
let result = crate::value_from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
let input = "val = { Struct = { value = -123 } }";
let expected = str![[r#"
Val {
val: Struct {
value: -123,
},
}
"#]];
let result = crate::from_str::<Val>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_std_table() {
let input = r#"[Struct]
value = -123
"#;
let expected = str![[r#"
Struct {
value: -123,
}
"#]];
let result = crate::from_str::<TheEnum>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_nested_std_table() {
let input = r#"[inner.Struct]
value = -123
"#;
let expected = str![[r#"
OuterStruct {
inner: Struct {
value: -123,
},
}
"#]];
let result = crate::from_str::<OuterStruct>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
}
mod enum_array {
use super::*;
#[test]
fn from_inline_tables() {
let input = r#"
enums = [
{ Plain = {} },
{ Tuple = { 0 = -123, 1 = true } },
{ NewType = "value" },
{ Struct = { value = -123 } }
]"#;
let expected = str![[r#"
Multi {
enums: [
Plain,
Tuple(
-123,
true,
),
NewType(
"value",
),
Struct {
value: -123,
},
],
}
"#]];
let result = crate::from_str::<Multi>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
#[test]
fn from_std_table() {
let input = r#"[[enums]]
Plain = {}
[[enums]]
Tuple = { 0 = -123, 1 = true }
[[enums]]
NewType = "value"
[[enums]]
Struct = { value = -123 }
"#;
let expected = str![[r#"
Multi {
enums: [
Plain,
Tuple(
-123,
true,
),
NewType(
"value",
),
Struct {
value: -123,
},
],
}
"#]];
let result = crate::from_str::<Multi>(input);
assert_data_eq!(result.unwrap().to_debug(), expected);
}
}