Skip to content

Commit 60d7ff0

Browse files
committed
feat: add support for QuickJS rope strings
1 parent 588b485 commit 60d7ff0

6 files changed

Lines changed: 360 additions & 3 deletions

File tree

src/serde/de.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
174174
JsTag::Bool => visitor.visit_bool(current.to_bool()?),
175175
JsTag::Null => visitor.visit_unit(),
176176
JsTag::String => visitor.visit_string(current.to_string()?),
177+
JsTag::RopeString => visitor.visit_string(current.to_string()?),
177178
JsTag::Float64 => visitor.visit_f64(current.to_float()?),
178179
JsTag::Object => {
179180
if current.is_array() {

src/value/tag.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub enum JsTag {
1212
BigInt = q::JS_TAG_BIG_INT,
1313
Symbol = q::JS_TAG_SYMBOL,
1414
String = q::JS_TAG_STRING,
15+
RopeString = q::JS_TAG_STRING_ROPE,
1516
Module = q::JS_TAG_MODULE,
1617
FunctionBytecode = q::JS_TAG_FUNCTION_BYTECODE,
1718
Object = q::JS_TAG_OBJECT,
@@ -39,6 +40,7 @@ impl JsTag {
3940
q::JS_TAG_MODULE => JsTag::Module,
4041
q::JS_TAG_OBJECT => JsTag::Object,
4142
q::JS_TAG_STRING => JsTag::String,
43+
q::JS_TAG_STRING_ROPE => JsTag::RopeString,
4244
q::JS_TAG_SYMBOL => JsTag::Symbol,
4345
q::JS_TAG_FLOAT64 => JsTag::Float64,
4446
q::JS_TAG_EXCEPTION => JsTag::Exception,
@@ -65,6 +67,7 @@ impl JsTag {
6567
JsTag::BigInt => q::JS_TAG_FUNCTION_BYTECODE,
6668
JsTag::Symbol => q::JS_TAG_SYMBOL,
6769
JsTag::String => q::JS_TAG_STRING,
70+
JsTag::RopeString => q::JS_TAG_STRING_ROPE,
6871
JsTag::Module => q::JS_TAG_MODULE,
6972
JsTag::FunctionBytecode => q::JS_TAG_FUNCTION_BYTECODE,
7073
JsTag::Object => q::JS_TAG_OBJECT,

src/value/value.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ impl OwnedJsValue {
251251
/// Check if this value is a Javascript string.
252252
#[inline]
253253
pub fn is_string(&self) -> bool {
254-
self.tag() == JsTag::String
254+
unsafe { q::JS_Ext_IsString(self.value) }
255255
}
256256

257257
/// Check if this value is a bytecode compiled function.
@@ -292,7 +292,8 @@ impl OwnedJsValue {
292292

293293
/// Convert this value into a string
294294
pub fn to_string(&self) -> Result<String, ValueError> {
295-
self.check_tag(JsTag::String)?;
295+
self.check_tag(JsTag::String)
296+
.or_else(|_| self.check_tag(JsTag::RopeString))?;
296297
let ptr =
297298
unsafe { q::JS_ToCStringLen2(self.context, std::ptr::null_mut(), self.value, false) };
298299

tests/convert.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ fn test_try_from_owned_js_value() {
3030
let value: String = js_value.try_into().unwrap();
3131
assert_eq!(value, "hello");
3232

33+
// test with rope string
34+
let js_value: OwnedJsValue = context
35+
.eval(
36+
&format!("var x = `{}`; x + x", include_str!("fixtures/long_string.txt")),
37+
false,
38+
)
39+
.unwrap();
40+
assert!(js_value.is_string());
41+
let value: String = js_value.try_into().unwrap();
42+
assert!(value.starts_with("Lorem ipsum"));
43+
3344
let js_value: OwnedJsValue = context.eval(r#"({"key": "value"})"#, false).unwrap();
3445
let value: HashMap<String, String> = js_value.try_into().unwrap();
3546
assert_eq!(value, HashMap::from([("key".into(), "value".into())]));

0 commit comments

Comments
 (0)