summaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAna Gelez <ana@gelez.xyz>2024-03-25 17:51:35 +0100
committerGitHub <noreply@github.com>2024-03-25 16:51:35 +0000
commit105d7156f8f9d95e16b3eefdf0fa97e5be7fbe5b (patch)
treee937ec63a9f95af3d6272525f8701ec0d4ed5582 /crates
parent2efa86cbdf3e60602fe5524aeaa0befdf14eafcf (diff)
Better handle large numbers from external data files (#3791)
Co-authored-by: Martin Haug <mhaug@live.de>
Diffstat (limited to 'crates')
-rw-r--r--crates/typst/src/foundations/int.rs9
-rw-r--r--crates/typst/src/loading/cbor.rs3
-rw-r--r--crates/typst/src/loading/json.rs17
-rw-r--r--crates/typst/src/loading/yaml.rs3
4 files changed, 25 insertions, 7 deletions
diff --git a/crates/typst/src/foundations/int.rs b/crates/typst/src/foundations/int.rs
index ef21f785..7b6c0263 100644
--- a/crates/typst/src/foundations/int.rs
+++ b/crates/typst/src/foundations/int.rs
@@ -261,7 +261,14 @@ macro_rules! unsigned_int {
($($ty:ty)*) => {
$(cast! {
$ty,
- self => Value::Int(self as _),
+ self => if let Ok(int) = i64::try_from(self) {
+ Value::Int(int)
+ } else {
+ // Some u64 are too large to be cast as i64
+ // In that case, we accept that there may be a
+ // precision loss, and use a floating point number
+ Value::Float(self as _)
+ },
v: i64 => v.try_into().map_err(|_| {
if v < 0 {
"number must be at least zero"
diff --git a/crates/typst/src/loading/cbor.rs b/crates/typst/src/loading/cbor.rs
index ddf559f3..bce09271 100644
--- a/crates/typst/src/loading/cbor.rs
+++ b/crates/typst/src/loading/cbor.rs
@@ -14,6 +14,9 @@ use crate::World;
/// equivalents, null-values (`null`, `~` or empty ``) will be converted into
/// `{none}`, and numbers will be converted to floats or integers depending on
/// whether they are whole numbers.
+///
+/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
+/// floating point numbers, which may result in an approximative value.
#[func(scope, title = "CBOR")]
pub fn cbor(
/// The engine.
diff --git a/crates/typst/src/loading/json.rs b/crates/typst/src/loading/json.rs
index aae1f4ad..8e829594 100644
--- a/crates/typst/src/loading/json.rs
+++ b/crates/typst/src/loading/json.rs
@@ -9,13 +9,18 @@ use crate::World;
/// Reads structured data from a JSON file.
///
-/// The file must contain a valid JSON object or array. JSON objects will be
-/// converted into Typst dictionaries, and JSON arrays will be converted into
-/// Typst arrays. Strings and booleans will be converted into the Typst
-/// equivalents, `null` will be converted into `{none}`, and numbers will be
-/// converted to floats or integers depending on whether they are whole numbers.
+/// The file must contain a valid JSON value, such as object or array. JSON
+/// objects will be converted into Typst dictionaries, and JSON arrays will be
+/// converted into Typst arrays. Strings and booleans will be converted into the
+/// Typst equivalents, `null` will be converted into `{none}`, and numbers will
+/// be converted to floats or integers depending on whether they are whole
+/// numbers.
///
-/// The function returns a dictionary or an array, depending on the JSON file.
+/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
+/// floating point numbers, which may result in an approximative value.
+///
+/// The function returns a dictionary, an array or, depending on the JSON file,
+/// another JSON data type.
///
/// The JSON files in the example contain objects with the keys `temperature`,
/// `unit`, and `weather`.
diff --git a/crates/typst/src/loading/yaml.rs b/crates/typst/src/loading/yaml.rs
index 501e3066..d578eda4 100644
--- a/crates/typst/src/loading/yaml.rs
+++ b/crates/typst/src/loading/yaml.rs
@@ -17,6 +17,9 @@ use crate::World;
/// whether they are whole numbers. Custom YAML tags are ignored, though the
/// loaded value will still be present.
///
+/// Be aware that integers larger than 2<sup>63</sup>-1 will be converted to
+/// floating point numbers, which may give an approximative value.
+///
/// The YAML files in the example contain objects with authors as keys,
/// each with a sequence of their own submapping with the keys
/// "title" and "published"