Repository: toml-rs/toml
Pull request #958 (2025-06-18 19:25:15)

feat(toml): Add support for bignum, u64, u128, i128
Regarding integers, the TOML spec says

> Arbitrary 64-bit signed integers (from −2^63 to 2^63−1) should be accepted and handled losslessly. If an integer cannot be represented losslessly, an error must be thrown.

Regarding floats:

> Floats should be implemented as IEEE 754 binary64 values.

toml-lang/toml#1058 is clarifying these to mean that larger of both is allowed.

This PR adds parse support to `toml` for big num, `u64`, `u128`, and `i128`.  This only adds deserialization support for `u64`, `u128`, and `i128`.  This does not yet add any serialization support or `toml::Value` support for any of these.

As this just defers what we were already going to to and the happy path was what we were already doing, I didn't bother putting this behind a feature flag like `serde_json`.


Patch:
diff --git a/crates/toml/src/de/dearray.rs b/crates/toml/src/de/dearray.rs
index 59f07dfe..f8c90e2f 100644
--- a/crates/toml/src/de/dearray.rs
+++ b/crates/toml/src/de/dearray.rs
@@ -132,15 +132,6 @@ impl Default for DeArray<'static> {
     }
 }
 
-impl PartialEq for DeArray<'_> {
-    #[inline]
-    fn eq(&self, other: &Self) -> bool {
-        self.items.eq(&other.items)
-    }
-}
-
-impl Eq for DeArray<'_> {}
-
 impl core::fmt::Debug for DeArray<'_> {
     #[inline]
     fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
diff --git a/crates/toml/src/de/devalue.rs b/crates/toml/src/de/devalue.rs
index d7a0b0ca..f8866ba6 100644
--- a/crates/toml/src/de/devalue.rs
+++ b/crates/toml/src/de/devalue.rs
@@ -14,15 +14,105 @@ use crate::de::DeTable;
 /// Type representing a TOML string, payload of the `DeValue::String` variant
 pub type DeString<'i> = Cow<'i, str>;
 
+/// Represents a TOML integer
+#[derive(Clone, Debug)]
+pub struct DeInteger<'i> {
+    pub(crate) inner: DeString<'i>,
+    pub(crate) radix: u32,
+}
+
+impl DeInteger<'_> {
+    pub(crate) fn to_u64(&self) -> Option<u64> {
+        u64::from_str_radix(self.inner.as_ref(), self.radix).ok()
+    }
+    pub(crate) fn to_i64(&self) -> Option<i64> {
+        i64::from_str_radix(self.inner.as_ref(), self.radix).ok()
+    }
+    pub(crate) fn to_u128(&self) -> Option<u128> {
+        u128::from_str_radix(self.inner.as_ref(), self.radix).ok()
+    }
+    pub(crate) fn to_i128(&self) -> Option<i128> {
+        i128::from_str_radix(self.inner.as_ref(), self.radix).ok()
+    }
+
+    pub(crate) fn as_str(&self) -> &str {
+        self.inner.as_ref()
+    }
+}
+
+impl Default for DeInteger<'_> {
+    fn default() -> Self {
+        Self {
+            inner: DeString::Borrowed("0"),
+            radix: 10,
+        }
+    }
+}
+
+impl core::fmt::Display for DeInteger<'_> {
+    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        match self.radix {
+            2 => "0b".fmt(formatter)?,
+            8 => "0o".fmt(formatter)?,
+            10 => {}
+            16 => "0x".fmt(formatter)?,
+            _ => {
+                unreachable!(
+                    "we should only ever have 2, 8, 10, and 16 radix, not {}",
+                    self.radix
+                )
+            }
+        }
+        self.as_str().fmt(formatter)?;
+        Ok(())
+    }
+}
+
+/// Represents a TOML integer
+#[derive(Clone, Debug)]
+pub struct DeFloat<'i> {
+    pub(crate) inner: DeString<'i>,
+}
+
+impl DeFloat<'_> {
+    pub(crate) fn to_f64(&self) -> Option<f64> {
+        let f: f64 = self.inner.as_ref().parse().ok()?;
+        if f.is_infinite() && !self.as_str().contains("inf") {
+            None
+        } else {
+            Some(f)
+        }
+    }
+
+    pub(crate) fn as_str(&self) -> &str {
+        self.inner.as_ref()
+    }
+}
+
+impl Default for DeFloat<'_> {
+    fn default() -> Self {
+        Self {
+            inner: DeString::Borrowed("0.0"),
+        }
+    }
+}
+
+impl core::fmt::Display for DeFloat<'_> {
+    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        self.as_str().fmt(formatter)?;
+        Ok(())
+    }
+}
+
 /// Representation of a TOML value.
-#[derive(PartialEq, Clone, Debug)]
+#[derive(Clone, Debug)]
 pub enum DeValue<'i> {
     /// Represents a TOML string
     String(DeString<'i>),
     /// Represents a TOML integer
-    Integer(i64),
+    Integer(DeInteger<'i>),
     /// Represents a TOML float
-    Float(f64),
+    Float(DeFloat<'i>),
     /// Represents a TOML boolean
     Boolean(bool),
     /// Represents a TOML datetime
@@ -87,8 +177,8 @@ impl<'i> DeValue<'i> {
     }
 
     /// Extracts the integer value if it is an integer.
-    pub fn as_integer(&self) -> Option<i64> {
-        match *self {
+    pub fn as_integer(&self) -> Option<&DeInteger<'i>> {
+        match self {
             DeValue::Integer(i) => Some(i),
             _ => None,
         }
@@ -100,8 +190,8 @@ impl<'i> DeValue<'i> {
     }
 
     /// Extracts the float value if it is a float.
-    pub fn as_float(&self) -> Option<f64> {
-        match *self {
+    pub fn as_float(&self) -> Option<&DeFloat<'i>> {
+        match self {
             DeValue::Float(f) => Some(f),
             _ => None,
         }
diff --git a/crates/toml/src/de/error.rs b/crates/toml/src/de/error.rs
index fbebfe55..e23dc8f2 100644
--- a/crates/toml/src/de/error.rs
+++ b/crates/toml/src/de/error.rs
@@ -4,14 +4,14 @@ use crate::alloc_prelude::*;
 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct Error {
     message: String,
-    raw: Option<alloc::sync::Arc<str>>,
+    input: Option<alloc::sync::Arc<str>>,
     keys: Vec<String>,
     span: Option<core::ops::Range<usize>>,
 }
 
 impl Error {
     #[cfg(feature = "parse")]
-    pub(crate) fn new(raw: alloc::sync::Arc<str>, error: toml_parse::ParseError) -> Self {
+    pub(crate) fn new(input: alloc::sync::Arc<str>, error: toml_parse::ParseError) -> Self {
         let mut message = String::new();
         message.push_str(error.description());
         if let Some(expected) = error.expected() {
@@ -38,7 +38,7 @@ impl Error {
 
         Self {
             message,
-            raw: Some(raw),
+            input: Some(input),
             keys: Vec::new(),
             span,
         }
@@ -50,7 +50,7 @@ impl Error {
     {
         Self {
             message: msg.to_string(),
-            raw: None,
+            input: None,
             keys: Vec::new(),
             span,
         }
@@ -74,8 +74,9 @@ impl Error {
         self.span = span;
     }
 
-    pub(crate) fn set_raw(&mut self, raw: Option<String>) {
-        self.raw = raw.map(|s| s.into());
+    /// Provide the encoded TOML the error applies to
+    pub fn set_input(&mut self, input: Option<&str>) {
+        self.input = input.map(|s| s.into());
     }
 }
 
@@ -114,14 +115,14 @@ fn render_literal(literal: &str) -> String {
 impl core::fmt::Display for Error {
     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
         let mut context = false;
-        if let (Some(raw), Some(span)) = (&self.raw, self.span()) {
+        if let (Some(input), Some(span)) = (&self.input, self.span()) {
             context = true;
 
-            let (line, column) = translate_position(raw.as_bytes(), span.start);
+            let (line, column) = translate_position(input.as_bytes(), span.start);
             let line_num = line + 1;
             let col_num = column + 1;
             let gutter = line_num.to_string().len();
-            let content = raw.split('\n').nth(line).expect("valid line number");
+            let content = input.split('\n').nth(line).expect("valid line number");
             let highlight_len = span.end - span.start;
             // Allow highlight to go one past the line
             let highlight_len = highlight_len.min(content.len().saturating_sub(column));
@@ -199,7 +200,7 @@ fn translate_position(input: &[u8], index: usize) -> (usize, usize) {
 #[cfg(feature = "parse")]
 pub(crate) struct TomlSink<'i, S> {
     source: toml_parse::Source<'i>,
-    raw: Option<alloc::sync::Arc<str>>,
+    input: Option<alloc::sync::Arc<str>>,
     sink: S,
 }
 
@@ -208,7 +209,7 @@ impl<'i, S: Default> TomlSink<'i, S> {
     pub(crate) fn new(source: toml_parse::Source<'i>) -> Self {
         Self {
             source,
-            raw: None,
+            input: None,
             sink: Default::default(),
         }
     }
@@ -222,10 +223,10 @@ impl<'i, S: Default> TomlSink<'i, S> {
 impl<'i> toml_parse::ErrorSink for TomlSink<'i, Option<Error>> {
     fn report_error(&mut self, error: toml_parse::ParseError) {
         if self.sink.is_none() {
-            let raw = self
-                .raw
+            let input = self
+                .input
                 .get_or_insert_with(|| alloc::sync::Arc::from(self.source.input()));
-            let error = Error::new(raw.clone(), error);
+            let error = Error::new(input.clone(), error);
             self.sink = Some(error);
         }
     }
@@ -234,10 +235,10 @@ impl<'i> toml_parse::ErrorSink for TomlSink<'i, Option<Error>> {
 #[cfg(feature = "parse")]
 impl<'i> toml_parse::ErrorSink for TomlSink<'i, Vec<Error>> {
     fn report_error(&mut self, error: toml_parse::ParseError) {
-        let raw = self
-            .raw
+        let input = self
+            .input
             .get_or_insert_with(|| alloc::sync::Arc::from(self.source.input()));
-        let error = Error::new(raw.clone(), error);
+        let error = Error::new(input.clone(), error);
         self.sink.push(error);
     }
 }
diff --git a/crates/toml/src/de/mod.rs b/crates/toml/src/de/mod.rs
index a43a4c18..3bb3fe95 100644
--- a/crates/toml/src/de/mod.rs
+++ b/crates/toml/src/de/mod.rs
@@ -33,6 +33,10 @@ pub use dearray::DeArray;
 #[cfg(feature = "parse")]
 pub use detable::DeTable;
 #[cfg(feature = "parse")]
+pub use devalue::DeFloat;
+#[cfg(feature = "parse")]
+pub use devalue::DeInteger;
+#[cfg(feature = "parse")]
 pub use devalue::DeString;
 #[cfg(feature = "parse")]
 pub use devalue::DeValue;
@@ -178,7 +182,7 @@ impl<'de> serde::Deserializer<'de> for Deserializer<'de> {
         self.into_table_de()
             .deserialize_any(visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                e.set_input(raw);
                 e
             })
     }
@@ -193,7 +197,7 @@ impl<'de> serde::Deserializer<'de> for Deserializer<'de> {
         self.into_table_de()
             .deserialize_option(visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                e.set_input(raw);
                 e
             })
     }
@@ -210,7 +214,7 @@ impl<'de> serde::Deserializer<'de> for Deserializer<'de> {
         self.into_table_de()
             .deserialize_newtype_struct(name, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                e.set_input(raw);
                 e
             })
     }
@@ -228,7 +232,7 @@ impl<'de> serde::Deserializer<'de> for Deserializer<'de> {
         self.into_table_de()
             .deserialize_struct(name, fields, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                e.set_input(raw);
                 e
             })
     }
@@ -247,7 +251,7 @@ impl<'de> serde::Deserializer<'de> for Deserializer<'de> {
         self.into_table_de()
             .deserialize_enum(name, variants, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                e.set_input(raw);
                 e
             })
     }
diff --git a/crates/toml/src/de/parser/value.rs b/crates/toml/src/de/parser/value.rs
index 079234c6..cf3935bb 100644
--- a/crates/toml/src/de/parser/value.rs
+++ b/crates/toml/src/de/parser/value.rs
@@ -4,6 +4,8 @@ use crate::alloc_prelude::*;
 use crate::de::parser::array::on_array;
 use crate::de::parser::inline_table::on_inline_table;
 use crate::de::parser::prelude::*;
+use crate::de::DeFloat;
+use crate::de::DeInteger;
 use crate::de::DeValue;
 
 /// ```bnf
@@ -56,7 +58,7 @@ pub(crate) fn value<'i>(
         }
     }
 
-    Spanned::new(0..0, DeValue::Integer(0))
+    Spanned::new(0..0, DeValue::Integer(Default::default()))
 }
 
 pub(crate) fn on_scalar<'i>(
@@ -99,43 +101,14 @@ pub(crate) fn on_scalar<'i>(
             Spanned::new(value_span, DeValue::Datetime(value))
         }
         toml_parse::decoder::ScalarKind::Float => {
-            let value = match decoded.parse::<f64>() {
-                Ok(value) => {
-                    if value.is_infinite()
-                        && !(decoded
-                            .strip_prefix(['+', '-'])
-                            .unwrap_or(&decoded)
-                            .chars()
-                            .all(|c| c.is_ascii_alphabetic()))
-                    {
-                        errors.report_error(
-                            ParseError::new("floating-point number overflowed")
-                                .with_unexpected(event.span()),
-                        );
-                    }
-                    value
-                }
-                Err(_) => {
-                    errors.report_error(
-                        ParseError::new(kind.invalid_description()).with_unexpected(event.span()),
-                    );
-                    f64::NAN
-                }
-            };
-            Spanned::new(value_span, DeValue::Float(value))
-        }
-        toml_parse::decoder::ScalarKind::Integer(radix) => {
-            let value = match i64::from_str_radix(&decoded, radix.value()) {
-                Ok(value) => value,
-                Err(_) => {
-                    // Assuming the decoder fully validated it, leaving only overflow errors
-                    errors.report_error(
-                        ParseError::new("integer number overflowed").with_unexpected(event.span()),
-                    );
-                    i64::MAX
-                }
-            };
-            Spanned::new(value_span, DeValue::Integer(value))
+            Spanned::new(value_span, DeValue::Float(DeFloat { inner: decoded }))
         }
+        toml_parse::decoder::ScalarKind::Integer(radix) => Spanned::new(
+            value_span,
+            DeValue::Integer(DeInteger {
+                inner: decoded,
+                radix: radix.value(),
+            }),
+        ),
     }
 }
diff --git a/crates/toml/src/de/value.rs b/crates/toml/src/de/value.rs
index 48afb875..48fd9408 100644
--- a/crates/toml/src/de/value.rs
+++ b/crates/toml/src/de/value.rs
@@ -90,8 +90,26 @@ impl<'de> serde::Deserializer<'de> for ValueDeserializer<'de> {
         match self.input {
             DeValue::String(DeString::Owned(v)) => visitor.visit_string(v),
             DeValue::String(DeString::Borrowed(v)) => visitor.visit_str(v),
-            DeValue::Integer(v) => visitor.visit_i64(v),
-            DeValue::Float(v) => visitor.visit_f64(v),
+            DeValue::Integer(v) => {
+                if let Some(v) = v.to_i64() {
+                    visitor.visit_i64(v)
+                } else if let Some(v) = v.to_u64() {
+                    visitor.visit_u64(v)
+                } else if let Some(v) = v.to_i128() {
+                    visitor.visit_i128(v)
+                } else if let Some(v) = v.to_u128() {
+                    visitor.visit_u128(v)
+                } else {
+                    Err(Error::custom("integer number overflowed", None))
+                }
+            }
+            DeValue::Float(v) => {
+                if let Some(v) = v.to_f64() {
+                    visitor.visit_f64(v)
+                } else {
+                    Err(Error::custom("floating-point number overflowed", None))
+                }
+            }
             DeValue::Boolean(v) => visitor.visit_bool(v),
             DeValue::Datetime(v) => visitor.visit_map(DatetimeDeserializer::new(v)),
             DeValue::Array(v) => ArrayDeserializer::new(v, span.clone()).deserialize_any(visitor),
@@ -105,6 +123,20 @@ impl<'de> serde::Deserializer<'de> for ValueDeserializer<'de> {
         })
     }
 
+    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
+    where
+        V: serde::de::Visitor<'de>,
+    {
+        self.deserialize_any(visitor)
+    }
+
+    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
+    where
+        V: serde::de::Visitor<'de>,
+    {
+        self.deserialize_any(visitor)
+    }
+
     // `None` is interpreted as a missing field so be sure to implement `Some`
     // as a present field.
     fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
diff --git a/crates/toml_edit/src/de/error.rs b/crates/toml_edit/src/de/error.rs
index 5c091128..fa87fca5 100644
--- a/crates/toml_edit/src/de/error.rs
+++ b/crates/toml_edit/src/de/error.rs
@@ -33,8 +33,9 @@ impl Error {
         self.inner.set_span(span);
     }
 
-    pub(crate) fn set_raw(&mut self, raw: Option<String>) {
-        self.inner.set_raw(raw);
+    /// Provide the encoded TOML the error applies to
+    pub fn set_input(&mut self, input: Option<&str>) {
+        self.inner.set_input(input);
     }
 }
 
diff --git a/crates/toml_edit/src/de/mod.rs b/crates/toml_edit/src/de/mod.rs
index 74a1337e..225687fa 100644
--- a/crates/toml_edit/src/de/mod.rs
+++ b/crates/toml_edit/src/de/mod.rs
@@ -131,7 +131,7 @@ impl std::str::FromStr for Deserializer {
     }
 }
 
-impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
+impl<'de, S: AsRef<str>> serde::Deserializer<'de> for Deserializer<S> {
     type Error = Error;
 
     fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -142,7 +142,8 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
         ValueDeserializer::new(self.root)
             .deserialize_any(visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                let raw = raw.as_ref().map(|r| r.as_ref());
+                e.set_input(raw);
                 e
             })
     }
@@ -157,7 +158,8 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
         ValueDeserializer::new(self.root)
             .deserialize_option(visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                let raw = raw.as_ref().map(|r| r.as_ref());
+                e.set_input(raw);
                 e
             })
     }
@@ -174,7 +176,8 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
         ValueDeserializer::new(self.root)
             .deserialize_newtype_struct(name, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                let raw = raw.as_ref().map(|r| r.as_ref());
+                e.set_input(raw);
                 e
             })
     }
@@ -192,7 +195,8 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
         ValueDeserializer::new(self.root)
             .deserialize_struct(name, fields, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                let raw = raw.as_ref().map(|r| r.as_ref());
+                e.set_input(raw);
                 e
             })
     }
@@ -211,7 +215,8 @@ impl<'de, S: Into<String>> serde::Deserializer<'de> for Deserializer<S> {
         ValueDeserializer::new(self.root)
             .deserialize_enum(name, variants, visitor)
             .map_err(|mut e: Self::Error| {
-                e.set_raw(raw.map(|r| r.into()));
+                let raw = raw.as_ref().map(|r| r.as_ref());
+                e.set_input(raw);
                 e
             })
     }
diff --git a/crates/toml_edit/src/error.rs b/crates/toml_edit/src/error.rs
index f68a7c66..021df9e8 100644
--- a/crates/toml_edit/src/error.rs
+++ b/crates/toml_edit/src/error.rs
@@ -2,14 +2,14 @@
 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
 pub struct TomlError {
     message: String,
-    raw: Option<std::sync::Arc<str>>,
+    input: Option<std::sync::Arc<str>>,
     keys: Vec<String>,
     span: Option<std::ops::Range<usize>>,
 }
 
 impl TomlError {
     #[cfg(feature = "parse")]
-    pub(crate) fn new(raw: std::sync::Arc<str>, error: toml_parse::ParseError) -> Self {
+    pub(crate) fn new(input: std::sync::Arc<str>, error: toml_parse::ParseError) -> Self {
         let mut message = String::new();
         message.push_str(error.description());
         if let Some(expected) = error.expected() {
@@ -36,7 +36,7 @@ impl TomlError {
 
         Self {
             message,
-            raw: Some(raw),
+            input: Some(input),
             keys: Vec::new(),
             span,
         }
@@ -46,7 +46,7 @@ impl TomlError {
     pub(crate) fn custom(message: String, span: Option<std::ops::Range<usize>>) -> Self {
         Self {
             message,
-            raw: None,
+            input: None,
             keys: Vec::new(),
             span,
         }
@@ -73,8 +73,8 @@ impl TomlError {
     }
 
     #[cfg(feature = "serde")]
-    pub(crate) fn set_raw(&mut self, raw: Option<String>) {
-        self.raw = raw.map(|s| s.into());
+    pub(crate) fn set_input(&mut self, input: Option<&str>) {
+        self.input = input.map(|s| s.into());
     }
 }
 
@@ -104,14 +104,14 @@ fn render_literal(literal: &str) -> String {
 impl std::fmt::Display for TomlError {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         let mut context = false;
-        if let (Some(raw), Some(span)) = (&self.raw, self.span()) {
+        if let (Some(input), Some(span)) = (&self.input, self.span()) {
             context = true;
 
-            let (line, column) = translate_position(raw.as_bytes(), span.start);
+            let (line, column) = translate_position(input.as_bytes(), span.start);
             let line_num = line + 1;
             let col_num = column + 1;
             let gutter = line_num.to_string().len();
-            let content = raw.split('\n').nth(line).expect("valid line number");
+            let content = input.split('\n').nth(line).expect("valid line number");
             let highlight_len = span.end - span.start;
             // Allow highlight to go one past the line
             let highlight_len = highlight_len.min(content.len().saturating_sub(column));
@@ -186,7 +186,7 @@ fn translate_position(input: &[u8], index: usize) -> (usize, usize) {
 #[cfg(feature = "parse")]
 pub(crate) struct TomlSink<'i, S> {
     source: toml_parse::Source<'i>,
-    raw: Option<std::sync::Arc<str>>,
+    input: Option<std::sync::Arc<str>>,
     sink: S,
 }
 
@@ -195,7 +195,7 @@ impl<'i, S: Default> TomlSink<'i, S> {
     pub(crate) fn new(source: toml_parse::Source<'i>) -> Self {
         Self {
             source,
-            raw: None,
+            input: None,
             sink: Default::default(),
         }
     }
@@ -209,10 +209,10 @@ impl<'i, S: Default> TomlSink<'i, S> {
 impl<'i> toml_parse::ErrorSink for TomlSink<'i, Option<TomlError>> {
     fn report_error(&mut self, error: toml_parse::ParseError) {
         if self.sink.is_none() {
-            let raw = self
-                .raw
+            let input = self
+                .input
                 .get_or_insert_with(|| std::sync::Arc::from(self.source.input()));
-            let error = TomlError::new(raw.clone(), error);
+            let error = TomlError::new(input.clone(), error);
             self.sink = Some(error);
         }
     }
@@ -221,10 +221,10 @@ impl<'i> toml_parse::ErrorSink for TomlSink<'i, Option<TomlError>> {
 #[cfg(feature = "parse")]
 impl<'i> toml_parse::ErrorSink for TomlSink<'i, Vec<TomlError>> {
     fn report_error(&mut self, error: toml_parse::ParseError) {
-        let raw = self
-            .raw
+        let input = self
+            .input
             .get_or_insert_with(|| std::sync::Arc::from(self.source.input()));
-        let error = TomlError::new(raw.clone(), error);
+        let error = TomlError::new(input.clone(), error);
         self.sink.push(error);
     }
 }


Test patch:
diff --git a/crates/toml/tests/decoder.rs b/crates/toml/tests/decoder.rs
index 9afe938c..2f0a9439 100644
--- a/crates/toml/tests/decoder.rs
+++ b/crates/toml/tests/decoder.rs
@@ -23,8 +23,11 @@ impl toml_test_harness::Decoder for Decoder {
             let error = toml_test_harness::Error::new(errors);
             return Err(error);
         }
-        let document = toml::Table::deserialize(toml::de::Deserializer::from(table))
-            .map_err(toml_test_harness::Error::new)?;
+        let document =
+            toml::Table::deserialize(toml::de::Deserializer::from(table)).map_err(|mut err| {
+                err.set_input(Some(data));
+                toml_test_harness::Error::new(err)
+            })?;
         let value = toml::Value::Table(document);
         value_to_decoded(&value)
     }
diff --git a/crates/toml/tests/fixtures/invalid/ext/integer/overflow-neg.toml b/crates/toml/tests/fixtures/invalid/ext/integer/overflow-neg.toml
index 20c7b554..78869d80 100644
--- a/crates/toml/tests/fixtures/invalid/ext/integer/overflow-neg.toml
+++ b/crates/toml/tests/fixtures/invalid/ext/integer/overflow-neg.toml
@@ -1,1 +1,1 @@
-a = -9223372036854775809
+a = -9223372036854775809123123123123123123123123123123123123123123123123123123123123
diff --git a/crates/toml/tests/fixtures/invalid/ext/integer/overflow-pos.toml b/crates/toml/tests/fixtures/invalid/ext/integer/overflow-pos.toml
index d12c93eb..83a6fb41 100644
--- a/crates/toml/tests/fixtures/invalid/ext/integer/overflow-pos.toml
+++ b/crates/toml/tests/fixtures/invalid/ext/integer/overflow-pos.toml
@@ -1,1 +1,1 @@
-a = 9223372036854775808
+a = 9223372036854775809123123123123123123123123123123123123123123123123123123123123
diff --git a/crates/toml/tests/serde/general.rs b/crates/toml/tests/serde/general.rs
index 5d38f2b3..c2ef7bbd 100644
--- a/crates/toml/tests/serde/general.rs
+++ b/crates/toml/tests/serde/general.rs
@@ -1032,7 +1032,7 @@ debug = true
 }
 
 #[test]
-fn integer_min() {
+fn i64_min() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
         a_b: i64,
@@ -1045,33 +1045,216 @@ fn integer_min() {
 }
 
 #[test]
-fn integer_too_big() {
+fn i64_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: i64,
+    }
+
+    equivalent! {
+        Foo { a_b: i64::MAX },
+        map! { a_b: crate::SerdeValue::Integer(i64::MAX) },
+    }
+}
+
+#[test]
+fn u64_max() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
         a_b: u64,
     }
 
-    let native = Foo { a_b: u64::MAX };
-    let err = crate::SerdeTable::try_from(native.clone()).unwrap_err();
-    assert_data_eq!(err.to_string(), str!["u64 value was too large"].raw());
-    let err = crate::to_string(&native).unwrap_err();
+    let value = u64::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
     assert_data_eq!(
-        err.to_string(),
+        crate::to_string(&literal).unwrap_err().to_string(),
         str!["out-of-range value for u64 type"].raw()
     );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap().to_debug(),
+        str![[r#"
+Foo {
+    a_b: 18446744073709551615,
+}
+
+"#]]
+        .raw()
+    );
+
+    // In/out of Value is equivalent
+    println!("Table::try_from(literal)");
+    assert_data_eq!(
+        toml::Table::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["u64 value was too large"].raw()
+    );
+    println!("Value::try_from(literal)");
+    assert_data_eq!(
+        toml::Value::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["u64 value was too large"].raw()
+    );
 }
 
 #[test]
-fn integer_max() {
+fn i128_min() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
-        a_b: i64,
+        a_b: i128,
     }
 
-    equivalent! {
-        Foo { a_b: i64::MAX },
-        map! { a_b: crate::SerdeValue::Integer(i64::MAX) },
+    let value = i128::MIN;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap().to_debug(),
+        str![[r#"
+Foo {
+    a_b: -170141183460469231731687303715884105728,
+}
+
+"#]]
+        .raw()
+    );
+
+    // In/out of Value is equivalent
+    println!("Table::try_from(literal)");
+    assert_data_eq!(
+        toml::Table::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("Value::try_from(literal)");
+    assert_data_eq!(
+        toml::Value::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["i128 is not supported"].raw()
+    );
+}
+
+#[test]
+fn i128_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: i128,
+    }
+
+    let value = i128::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap().to_debug(),
+        str![[r#"
+Foo {
+    a_b: 170141183460469231731687303715884105727,
+}
+
+"#]]
+        .raw()
+    );
+
+    // In/out of Value is equivalent
+    println!("Table::try_from(literal)");
+    assert_data_eq!(
+        toml::Table::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("Value::try_from(literal)");
+    assert_data_eq!(
+        toml::Value::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["i128 is not supported"].raw()
+    );
+}
+
+#[test]
+fn u128_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: u128,
     }
+
+    let value = u128::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["u128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap().to_debug(),
+        str![[r#"
+Foo {
+    a_b: 340282366920938463463374607431768211455,
+}
+
+"#]]
+        .raw()
+    );
+
+    // In/out of Value is equivalent
+    println!("Table::try_from(literal)");
+    assert_data_eq!(
+        toml::Table::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["u128 is not supported"].raw()
+    );
+    println!("Value::try_from(literal)");
+    assert_data_eq!(
+        toml::Value::try_from(literal.clone())
+            .unwrap_err()
+            .to_string(),
+        str!["u128 is not supported"].raw()
+    );
 }
 
 #[test]
diff --git a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-minus.stderr b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-minus.stderr
index 8fc327a9..69b9910d 100644
--- a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-minus.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-minus.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 10
 1 | a = 0.0e-
   |          ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 5
-  |
-1 | a = 0.0e-
-  |     ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-plus.stderr b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-plus.stderr
index 47d168af..efbef03b 100644
--- a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-plus.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp-plus.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 10
 1 | a = 0.0e+
   |          ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 5
-  |
-1 | a = 0.0e+
-  |     ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp.stderr b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp.stderr
index 8a5fc0c9..4dd3cd23 100644
--- a/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/float/trailing-exp.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 9
 1 | a = 0.0E
   |         ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 5
-  |
-1 | a = 0.0E
-  |     ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/ext/float/trailing-point-exp.stderr b/crates/toml/tests/snapshots/invalid/ext/float/trailing-point-exp.stderr
index 34fa8422..37968f05 100644
--- a/crates/toml/tests/snapshots/invalid/ext/float/trailing-point-exp.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/float/trailing-point-exp.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 8
 1 | a = 0.e
   |        ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 5
-  |
-1 | a = 0.e
-  |     ^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/ext/integer/overflow-neg.stderr b/crates/toml/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
index 63aa688f..f24aeb94 100644
--- a/crates/toml/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
@@ -1,5 +1,5 @@
 TOML parse error at line 1, column 5
   |
-1 | a = -9223372036854775809
-  |     ^^^^^^^^^^^^^^^^^^^^
+1 | a = -9223372036854775809123123123123123123123123123123123123123123123123123123123123
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/ext/integer/overflow-pos.stderr b/crates/toml/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
index 0029f00a..0e6c2adf 100644
--- a/crates/toml/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
+++ b/crates/toml/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
@@ -1,5 +1,5 @@
 TOML parse error at line 1, column 5
   |
-1 | a = 9223372036854775808
-  |     ^^^^^^^^^^^^^^^^^^^
+1 | a = 9223372036854775809123123123123123123123123123123123123123123123123123123123123
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/float/double-dot-01.stderr b/crates/toml/tests/snapshots/invalid/float/double-dot-01.stderr
index 7baf3065..e14e5188 100644
--- a/crates/toml/tests/snapshots/invalid/float/double-dot-01.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/double-dot-01.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 20
 1 | double-point-1 = 0..1
   |                    ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | double-point-1 = 0..1
-  |                  ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/double-dot-02.stderr b/crates/toml/tests/snapshots/invalid/float/double-dot-02.stderr
index 726db9f3..8b1df55e 100644
--- a/crates/toml/tests/snapshots/invalid/float/double-dot-02.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/double-dot-02.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 21
 1 | double-point-2 = 0.1.2
   |                     ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | double-point-2 = 0.1.2
-  |                  ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/double-point-1.stderr b/crates/toml/tests/snapshots/invalid/float/double-point-1.stderr
index 7baf3065..e14e5188 100644
--- a/crates/toml/tests/snapshots/invalid/float/double-point-1.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/double-point-1.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 20
 1 | double-point-1 = 0..1
   |                    ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | double-point-1 = 0..1
-  |                  ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/double-point-2.stderr b/crates/toml/tests/snapshots/invalid/float/double-point-2.stderr
index 726db9f3..8b1df55e 100644
--- a/crates/toml/tests/snapshots/invalid/float/double-point-2.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/double-point-2.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 21
 1 | double-point-2 = 0.1.2
   |                     ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | double-point-2 = 0.1.2
-  |                  ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-dot-01.stderr b/crates/toml/tests/snapshots/invalid/float/exp-dot-01.stderr
index 3dc00067..10406b1f 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-dot-01.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-dot-01.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 18
 1 | exp-point-1 = 1e2.3
   |                  ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 15
-  |
-1 | exp-point-1 = 1e2.3
-  |               ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-double-e-01.stderr b/crates/toml/tests/snapshots/invalid/float/exp-double-e-01.stderr
index 752b3761..46f44a7c 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-double-e-01.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-double-e-01.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 20
 1 | exp-double-e-1 = 1ee2
   |                    ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | exp-double-e-1 = 1ee2
-  |                  ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-double-e-02.stderr b/crates/toml/tests/snapshots/invalid/float/exp-double-e-02.stderr
index c048bcae..bfa21841 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-double-e-02.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-double-e-02.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 21
 1 | exp-double-e-2 = 1e2e3
   |                     ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | exp-double-e-2 = 1e2e3
-  |                  ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-double-e-1.stderr b/crates/toml/tests/snapshots/invalid/float/exp-double-e-1.stderr
index 752b3761..46f44a7c 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-double-e-1.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-double-e-1.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 20
 1 | exp-double-e-1 = 1ee2
   |                    ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | exp-double-e-1 = 1ee2
-  |                  ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-double-e-2.stderr b/crates/toml/tests/snapshots/invalid/float/exp-double-e-2.stderr
index c048bcae..bfa21841 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-double-e-2.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-double-e-2.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 21
 1 | exp-double-e-2 = 1e2e3
   |                     ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | exp-double-e-2 = 1e2e3
-  |                  ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/exp-point-1.stderr b/crates/toml/tests/snapshots/invalid/float/exp-point-1.stderr
index 3dc00067..10406b1f 100644
--- a/crates/toml/tests/snapshots/invalid/float/exp-point-1.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/exp-point-1.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 18
 1 | exp-point-1 = 1e2.3
   |                  ^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 15
-  |
-1 | exp-point-1 = 1e2.3
-  |               ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/trailing-exp-minus.stderr b/crates/toml/tests/snapshots/invalid/float/trailing-exp-minus.stderr
index ffdb7d9b..bc05b283 100644
--- a/crates/toml/tests/snapshots/invalid/float/trailing-exp-minus.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/trailing-exp-minus.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 27
 1 | trailing-exp-minus = 0.0e-
   |                           ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 22
-  |
-1 | trailing-exp-minus = 0.0e-
-  |                      ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/trailing-exp-plus.stderr b/crates/toml/tests/snapshots/invalid/float/trailing-exp-plus.stderr
index f5113e4a..b937e677 100644
--- a/crates/toml/tests/snapshots/invalid/float/trailing-exp-plus.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/trailing-exp-plus.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 26
 1 | trailing-exp-plus = 0.0e+
   |                          ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 21
-  |
-1 | trailing-exp-plus = 0.0e+
-  |                     ^^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/trailing-exp-point.stderr b/crates/toml/tests/snapshots/invalid/float/trailing-exp-point.stderr
index 1c18e40c..df6e16e5 100644
--- a/crates/toml/tests/snapshots/invalid/float/trailing-exp-point.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/trailing-exp-point.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 26
 1 | trailing-exp-point =  0.e
   |                          ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 23
-  |
-1 | trailing-exp-point =  0.e
-  |                       ^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/float/trailing-exp.stderr b/crates/toml/tests/snapshots/invalid/float/trailing-exp.stderr
index 19d59deb..9c40a09e 100644
--- a/crates/toml/tests/snapshots/invalid/float/trailing-exp.stderr
+++ b/crates/toml/tests/snapshots/invalid/float/trailing-exp.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 20
 1 | trailing-exp = 0.0E
   |                    ^
 invalid exponent, expected digits
-
----
-TOML parse error at line 1, column 16
-  |
-1 | trailing-exp = 0.0E
-  |                ^^^^
-invalid float
diff --git a/crates/toml/tests/snapshots/invalid/integer/double-sign-nex.stderr b/crates/toml/tests/snapshots/invalid/integer/double-sign-nex.stderr
index 5d261fc6..ef0c0d02 100644
--- a/crates/toml/tests/snapshots/invalid/integer/double-sign-nex.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/double-sign-nex.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 20
 1 | double-sign-nex = --99
   |                    ^
 redundant numeric sign, expected nothing
-
----
-TOML parse error at line 1, column 19
-  |
-1 | double-sign-nex = --99
-  |                   ^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/double-sign-plus.stderr b/crates/toml/tests/snapshots/invalid/integer/double-sign-plus.stderr
index 00b6ce9b..25da46c4 100644
--- a/crates/toml/tests/snapshots/invalid/integer/double-sign-plus.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/double-sign-plus.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 21
 1 | double-sign-plus = ++99
   |                     ^
 redundant numeric sign, expected nothing
-
----
-TOML parse error at line 1, column 20
-  |
-1 | double-sign-plus = ++99
-  |                    ^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-bin.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-bin.stderr
index 15c6fc1e..a603a25e 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-bin.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-bin.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 20
 1 | invalid-bin = 0b0012
   |                    ^
 invalid binary number
-
----
-TOML parse error at line 1, column 15
-  |
-1 | invalid-bin = 0b0012
-  |               ^^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-01.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-01.stderr
index 23ef96ce..01830157 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-01.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-01.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 22
 1 | invalid-hex-1 = 0xaafz
   |                      ^
 invalid hexadecimal number
-
----
-TOML parse error at line 1, column 17
-  |
-1 | invalid-hex-1 = 0xaafz
-  |                 ^^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-02.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-02.stderr
index f6f9d2e1..9805b513 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-02.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-02.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 19
 1 | invalid-hex-2 = 0xgabba00f1
   |                   ^
 invalid hexadecimal number
-
----
-TOML parse error at line 1, column 17
-  |
-1 | invalid-hex-2 = 0xgabba00f1
-  |                 ^^^^^^^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-1.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-1.stderr
index 23ef96ce..01830157 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-1.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-1.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 22
 1 | invalid-hex-1 = 0xaafz
   |                      ^
 invalid hexadecimal number
-
----
-TOML parse error at line 1, column 17
-  |
-1 | invalid-hex-1 = 0xaafz
-  |                 ^^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-2.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-2.stderr
index f6f9d2e1..9805b513 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-hex-2.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-hex-2.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 19
 1 | invalid-hex-2 = 0xgabba00f1
   |                   ^
 invalid hexadecimal number
-
----
-TOML parse error at line 1, column 17
-  |
-1 | invalid-hex-2 = 0xgabba00f1
-  |                 ^^^^^^^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/invalid-oct.stderr b/crates/toml/tests/snapshots/invalid/integer/invalid-oct.stderr
index 11a382f1..7d4b18ff 100644
--- a/crates/toml/tests/snapshots/invalid/integer/invalid-oct.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/invalid-oct.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 19
 1 | invalid-oct = 0o778
   |                   ^
 invalid octal number
-
----
-TOML parse error at line 1, column 15
-  |
-1 | invalid-oct = 0o778
-  |               ^^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/leading-us-bin.stderr b/crates/toml/tests/snapshots/invalid/integer/leading-us-bin.stderr
index 4d69a9de..c3765b19 100644
--- a/crates/toml/tests/snapshots/invalid/integer/leading-us-bin.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/leading-us-bin.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 18
 1 | leading-us-bin = _0b1
   |                  ^
 `_` may only go between digits, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | leading-us-bin = _0b1
-  |                  ^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/leading-us-hex.stderr b/crates/toml/tests/snapshots/invalid/integer/leading-us-hex.stderr
index cc8ea6c4..5e330b9b 100644
--- a/crates/toml/tests/snapshots/invalid/integer/leading-us-hex.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/leading-us-hex.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 18
 1 | leading-us-hex = _0x1
   |                  ^
 `_` may only go between digits, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | leading-us-hex = _0x1
-  |                  ^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/leading-us-oct.stderr b/crates/toml/tests/snapshots/invalid/integer/leading-us-oct.stderr
index f16d16e2..fc139af4 100644
--- a/crates/toml/tests/snapshots/invalid/integer/leading-us-oct.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/leading-us-oct.stderr
@@ -3,10 +3,3 @@ TOML parse error at line 1, column 18
 1 | leading-us-oct = _0o1
   |                  ^
 `_` may only go between digits, expected nothing
-
----
-TOML parse error at line 1, column 18
-  |
-1 | leading-us-oct = _0o1
-  |                  ^^^^
-integer number overflowed
diff --git a/crates/toml/tests/snapshots/invalid/integer/text-after-integer.stderr b/crates/toml/tests/snapshots/invalid/integer/text-after-integer.stderr
index 7d92c46e..d615a674 100644
--- a/crates/toml/tests/snapshots/invalid/integer/text-after-integer.stderr
+++ b/crates/toml/tests/snapshots/invalid/integer/text-after-integer.stderr
@@ -10,10 +10,3 @@ TOML parse error at line 1, column 12
 1 | answer = 42 the ultimate answer?
   |            ^^^^
 invalid float, expected nothing
-
----
-TOML parse error at line 1, column 10
-  |
-1 | answer = 42 the ultimate answer?
-  |          ^^^^^^
-invalid float
diff --git a/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-neg.toml b/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-neg.toml
index 20c7b554..78869d80 100644
--- a/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-neg.toml
+++ b/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-neg.toml
@@ -1,1 +1,1 @@
-a = -9223372036854775809
+a = -9223372036854775809123123123123123123123123123123123123123123123123123123123123
diff --git a/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-pos.toml b/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-pos.toml
index d12c93eb..83a6fb41 100644
--- a/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-pos.toml
+++ b/crates/toml_edit/tests/fixtures/invalid/ext/integer/overflow-pos.toml
@@ -1,1 +1,1 @@
-a = 9223372036854775808
+a = 9223372036854775809123123123123123123123123123123123123123123123123123123123123
diff --git a/crates/toml_edit/tests/serde/general.rs b/crates/toml_edit/tests/serde/general.rs
index 0bc5c97b..28eaf71b 100644
--- a/crates/toml_edit/tests/serde/general.rs
+++ b/crates/toml_edit/tests/serde/general.rs
@@ -998,7 +998,7 @@ debug = true
 }
 
 #[test]
-fn integer_min() {
+fn i64_min() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
         a_b: i64,
@@ -1011,33 +1011,160 @@ fn integer_min() {
 }
 
 #[test]
-fn integer_too_big() {
+fn i64_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: i64,
+    }
+
+    equivalent! {
+        Foo { a_b: i64::MAX },
+        map! { a_b: crate::SerdeValue::Integer(i64::MAX) },
+    }
+}
+
+#[test]
+fn u64_max() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
         a_b: u64,
     }
 
-    let native = Foo { a_b: u64::MAX };
-    let err = crate::SerdeTable::try_from(native.clone()).unwrap_err();
-    assert_data_eq!(err.to_string(), str!["u64 value was too large"].raw());
-    let err = crate::to_string(&native).unwrap_err();
+    let value = u64::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
     assert_data_eq!(
-        err.to_string(),
+        crate::to_string(&literal).unwrap_err().to_string(),
         str!["out-of-range value for u64 type"].raw()
     );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap_err().to_string(),
+        str![[r#"
+TOML parse error at line 2, column 7
+  |
+2 | a_b = 18446744073709551615
+  |       ^^^^^^^^^^^^^^^^^^^^
+integer number overflowed
+
+"#]]
+        .raw()
+    );
 }
 
 #[test]
-fn integer_max() {
+fn i128_min() {
     #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
     struct Foo {
-        a_b: i64,
+        a_b: i128,
     }
 
-    equivalent! {
-        Foo { a_b: i64::MAX },
-        map! { a_b: crate::SerdeValue::Integer(i64::MAX) },
+    let value = i128::MIN;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap_err().to_string(),
+        str![[r#"
+TOML parse error at line 2, column 7
+  |
+2 | a_b = -170141183460469231731687303715884105728
+  |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+integer number overflowed
+
+"#]]
+        .raw()
+    );
+}
+
+#[test]
+fn i128_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: i128,
+    }
+
+    let value = i128::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["i128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap_err().to_string(),
+        str![[r#"
+TOML parse error at line 2, column 7
+  |
+2 | a_b = 170141183460469231731687303715884105727
+  |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+integer number overflowed
+
+"#]]
+        .raw()
+    );
+}
+
+#[test]
+fn u128_max() {
+    #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+    struct Foo {
+        a_b: u128,
     }
+
+    let value = u128::MAX;
+    let literal = Foo { a_b: value };
+    let encoded = format!(
+        "
+a_b = {value}
+"
+    );
+
+    // Through a string equivalent
+    println!("to_string");
+    assert_data_eq!(
+        crate::to_string(&literal).unwrap_err().to_string(),
+        str!["u128 is not supported"].raw()
+    );
+    println!("literal, from_str(toml)");
+    assert_data_eq!(
+        crate::from_str::<Foo>(&encoded).unwrap_err().to_string(),
+        str![[r#"
+TOML parse error at line 2, column 7
+  |
+2 | a_b = 340282366920938463463374607431768211455
+  |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+integer number overflowed
+
+"#]]
+        .raw()
+    );
 }
 
 #[test]
diff --git a/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-neg.stderr b/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
index 63aa688f..f24aeb94 100644
--- a/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
+++ b/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-neg.stderr
@@ -1,5 +1,5 @@
 TOML parse error at line 1, column 5
   |
-1 | a = -9223372036854775809
-  |     ^^^^^^^^^^^^^^^^^^^^
+1 | a = -9223372036854775809123123123123123123123123123123123123123123123123123123123123
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 integer number overflowed
diff --git a/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-pos.stderr b/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
index 0029f00a..0e6c2adf 100644
--- a/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
+++ b/crates/toml_edit/tests/snapshots/invalid/ext/integer/overflow-pos.stderr
@@ -1,5 +1,5 @@
 TOML parse error at line 1, column 5
   |
-1 | a = 9223372036854775808
-  |     ^^^^^^^^^^^^^^^^^^^
+1 | a = 9223372036854775809123123123123123123123123123123123123123123123123123123123123
+  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 integer number overflowed