summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-08-21 15:32:56 +0200
committerLaurenz <laurmaedje@gmail.com>2023-08-21 15:33:03 +0200
commitd52493938e9b070ca593246427c384c500c5c13e (patch)
tree1ba4af6dd640240b9ce141b48152a697ce42d96e
parent99ddbafc095695d278fba81d835e88ac23e9b990 (diff)
Make bytes joinable
-rw-r--r--crates/typst/src/eval/array.rs2
-rw-r--r--crates/typst/src/eval/bytes.rs27
-rw-r--r--crates/typst/src/eval/ops.rs2
-rw-r--r--tests/typ/compiler/bytes.typ11
4 files changed, 40 insertions, 2 deletions
diff --git a/crates/typst/src/eval/array.rs b/crates/typst/src/eval/array.rs
index d93b14e6..b98c9296 100644
--- a/crates/typst/src/eval/array.rs
+++ b/crates/typst/src/eval/array.rs
@@ -446,7 +446,7 @@ impl Add for Array {
}
impl AddAssign for Array {
- fn add_assign(&mut self, rhs: Array) {
+ fn add_assign(&mut self, rhs: Self) {
self.0.extend(rhs.0);
}
}
diff --git a/crates/typst/src/eval/bytes.rs b/crates/typst/src/eval/bytes.rs
index 5921f485..2e0c098f 100644
--- a/crates/typst/src/eval/bytes.rs
+++ b/crates/typst/src/eval/bytes.rs
@@ -1,6 +1,6 @@
use std::borrow::Cow;
use std::fmt::{self, Debug, Formatter};
-use std::ops::Deref;
+use std::ops::{Add, AddAssign, Deref};
use std::sync::Arc;
use comemo::Prehashed;
@@ -96,6 +96,31 @@ impl Debug for Bytes {
}
}
+impl Add for Bytes {
+ type Output = Self;
+
+ fn add(mut self, rhs: Self) -> Self::Output {
+ self += rhs;
+ self
+ }
+}
+
+impl AddAssign for Bytes {
+ fn add_assign(&mut self, rhs: Self) {
+ if rhs.is_empty() {
+ // Nothing to do
+ } else if self.is_empty() {
+ *self = rhs;
+ } else if Arc::strong_count(&self.0) == 1 && matches!(**self.0, Cow::Owned(_)) {
+ Arc::make_mut(&mut self.0).update(|cow| {
+ cow.to_mut().extend_from_slice(&rhs);
+ })
+ } else {
+ *self = Self::from([self.as_slice(), rhs.as_slice()].concat());
+ }
+ }
+}
+
impl Serialize for Bytes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
diff --git a/crates/typst/src/eval/ops.rs b/crates/typst/src/eval/ops.rs
index 32317599..f57f743f 100644
--- a/crates/typst/src/eval/ops.rs
+++ b/crates/typst/src/eval/ops.rs
@@ -26,6 +26,7 @@ pub fn join(lhs: Value, rhs: Value) -> StrResult<Value> {
(Str(a), Str(b)) => Str(a + b),
(Str(a), Symbol(b)) => Str(format_str!("{a}{b}")),
(Symbol(a), Str(b)) => Str(format_str!("{a}{b}")),
+ (Bytes(a), Bytes(b)) => Bytes(a + b),
(Content(a), Content(b)) => Content(a + b),
(Content(a), Symbol(b)) => Content(a + item!(text)(b.get().into())),
(Content(a), Str(b)) => Content(a + item!(text)(b.into())),
@@ -96,6 +97,7 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
(Str(a), Str(b)) => Str(a + b),
(Str(a), Symbol(b)) => Str(format_str!("{a}{b}")),
(Symbol(a), Str(b)) => Str(format_str!("{a}{b}")),
+ (Bytes(a), Bytes(b)) => Bytes(a + b),
(Content(a), Content(b)) => Content(a + b),
(Content(a), Symbol(b)) => Content(a + item!(text)(b.get().into())),
(Content(a), Str(b)) => Content(a + item!(text)(b.into())),
diff --git a/tests/typ/compiler/bytes.typ b/tests/typ/compiler/bytes.typ
index 32d0d573..fa724858 100644
--- a/tests/typ/compiler/bytes.typ
+++ b/tests/typ/compiler/bytes.typ
@@ -13,6 +13,17 @@
#test(array(bytes("Hello")), (0x48, 0x65, 0x6C, 0x6C, 0x6F))
---
+// Test addition and joining.
+#test(bytes((1, 2)) + bytes(()), bytes((1, 2)))
+#test(bytes((1, 2)) + bytes((3, 4)), bytes((1, 2, 3, 4)))
+#test(bytes(()) + bytes((3, 4)), bytes((3, 4)))
+#test(str({
+ bytes("Hello")
+ bytes((0x20,))
+ bytes("World")
+}), "Hello World")
+
+---
// Error: 8-14 expected string, array, or bytes, found dictionary
#bytes((a: 1))