diff --git a/crates/toml/tests/testsuite/serde.rs b/crates/toml/tests/testsuite/serde.rs index 8bbff56e..3b9f65a4 100644 --- a/crates/toml/tests/testsuite/serde.rs +++ b/crates/toml/tests/testsuite/serde.rs @@ -945,6 +945,20 @@ fn integer_min() { } } +#[test] +fn integer_too_big() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Foo { + a_b: u64, + } + + let native = Foo { a_b: u64::MAX }; + let err = Table::try_from(native.clone()).unwrap_err(); + snapbox::assert_eq("u64 value was too large", err.to_string()); + let err = toml::to_string(&native).unwrap_err(); + snapbox::assert_eq("out-of-range value for u64 type", err.to_string()); +} + #[test] fn integer_max() { #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] diff --git a/crates/toml_edit/src/ser/mod.rs b/crates/toml_edit/src/ser/mod.rs index 9d639013..2c310206 100644 --- a/crates/toml_edit/src/ser/mod.rs +++ b/crates/toml_edit/src/ser/mod.rs @@ -20,6 +20,8 @@ use crate::visit_mut::VisitMut; pub enum Error { /// Type could not be serialized to TOML UnsupportedType(Option<&'static str>), + /// Value was out of range for the given type + OutOfRange(Option<&'static str>), /// `None` could not be serialized to TOML UnsupportedNone, /// Key was not convertable to `String` for serializing to TOML @@ -53,6 +55,8 @@ impl std::fmt::Display for Error { match self { Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"), Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"), + Self::OutOfRange(Some(t)) => write!(formatter, "out-of-range value for {t} type"), + Self::OutOfRange(None) => write!(formatter, "out-of-range value"), Self::UnsupportedNone => "unsupported None value".fmt(formatter), Self::KeyNotString => "map key was not a string".fmt(formatter), Self::DateInvalid => "a serialized date was invalid".fmt(formatter), diff --git a/crates/toml_edit/src/ser/value.rs b/crates/toml_edit/src/ser/value.rs index f0f30401..cc7dfb77 100644 --- a/crates/toml_edit/src/ser/value.rs +++ b/crates/toml_edit/src/ser/value.rs @@ -98,7 +98,10 @@ impl serde::ser::Serializer for ValueSerializer { } fn serialize_u64(self, v: u64) -> Result { - self.serialize_i64(v as i64) + let v: i64 = v + .try_into() + .map_err(|_err| Error::OutOfRange(Some("u64")))?; + self.serialize_i64(v) } fn serialize_f32(self, v: f32) -> Result {