summaryrefslogtreecommitdiff
path: root/serde_v8/src/ser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'serde_v8/src/ser.rs')
-rw-r--r--serde_v8/src/ser.rs59
1 files changed, 59 insertions, 0 deletions
diff --git a/serde_v8/src/ser.rs b/serde_v8/src/ser.rs
index 8829b9fc3..ce7e8c707 100644
--- a/serde_v8/src/ser.rs
+++ b/serde_v8/src/ser.rs
@@ -339,11 +339,64 @@ impl<'a, 'b, 'c> ser::SerializeStruct
}
}
+pub struct MagicU16StringSerializer<'a, 'b, 'c> {
+ scope: ScopePtr<'a, 'b, 'c>,
+ ptr: Option<std::ptr::NonNull<u16>>,
+ len: Option<usize>,
+}
+
+impl<'a, 'b, 'c> MagicU16StringSerializer<'a, 'b, 'c> {
+ pub fn new(scope: ScopePtr<'a, 'b, 'c>) -> Self {
+ Self {
+ scope,
+ ptr: None,
+ len: None,
+ }
+ }
+}
+
+impl<'a, 'b, 'c> ser::SerializeStruct for MagicU16StringSerializer<'a, 'b, 'c> {
+ type Ok = JsValue<'a>;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized + Serialize>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<()> {
+ // Get u64 chunk
+ let transmuted = value.serialize(magic::FieldSerializer {})?;
+ match key {
+ magic::u16string::FIELD_PTR => {
+ self.ptr = std::ptr::NonNull::new(transmuted as *mut u16)
+ }
+ magic::u16string::FIELD_LEN => self.len = Some(transmuted as usize),
+ _ => unreachable!(),
+ }
+ Ok(())
+ }
+
+ fn end(self) -> JsResult<'a> {
+ // SAFETY: This function is only called from U16String::serialize(), which
+ // guarantees the Vec is still alive.
+ let slice = unsafe {
+ std::slice::from_raw_parts(self.ptr.unwrap().as_ptr(), self.len.unwrap())
+ };
+ let scope = &mut *self.scope.borrow_mut();
+
+ let v8_value =
+ v8::String::new_from_two_byte(scope, slice, v8::NewStringType::Normal)
+ .unwrap();
+ Ok(v8_value.into())
+ }
+}
+
// Dispatches between magic and regular struct serializers
pub enum StructSerializers<'a, 'b, 'c> {
Magic(MagicSerializer<'a>),
MagicBuffer(MagicBufferSerializer<'a, 'b, 'c>),
MagicByteString(MagicByteStringSerializer<'a, 'b, 'c>),
+ MagicU16String(MagicU16StringSerializer<'a, 'b, 'c>),
Regular(ObjectSerializer<'a, 'b, 'c>),
}
@@ -360,6 +413,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> {
StructSerializers::Magic(s) => s.serialize_field(key, value),
StructSerializers::MagicBuffer(s) => s.serialize_field(key, value),
StructSerializers::MagicByteString(s) => s.serialize_field(key, value),
+ StructSerializers::MagicU16String(s) => s.serialize_field(key, value),
StructSerializers::Regular(s) => s.serialize_field(key, value),
}
}
@@ -369,6 +423,7 @@ impl<'a, 'b, 'c> ser::SerializeStruct for StructSerializers<'a, 'b, 'c> {
StructSerializers::Magic(s) => s.end(),
StructSerializers::MagicBuffer(s) => s.end(),
StructSerializers::MagicByteString(s) => s.end(),
+ StructSerializers::MagicU16String(s) => s.end(),
StructSerializers::Regular(s) => s.end(),
}
}
@@ -607,6 +662,10 @@ impl<'a, 'b, 'c> ser::Serializer for Serializer<'a, 'b, 'c> {
let m = MagicByteStringSerializer::new(self.scope);
Ok(StructSerializers::MagicByteString(m))
}
+ magic::u16string::NAME => {
+ let m = MagicU16StringSerializer::new(self.scope);
+ Ok(StructSerializers::MagicU16String(m))
+ }
_ => {
let o = ObjectSerializer::new(self.scope, len);
Ok(StructSerializers::Regular(o))