diff options
Diffstat (limited to 'serde_v8/src/ser.rs')
-rw-r--r-- | serde_v8/src/ser.rs | 59 |
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)) |