From fb2019413045260f6bf36951500e30b83cefc580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Giovanny=20Guti=C3=A9rrez?= Date: Thu, 27 Apr 2023 17:38:16 -0500 Subject: [PATCH] feat: Add bindings for "v8::Set" (#1221) --- src/binding.cc | 32 ++++++++++++++++++++ src/object.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++ tests/test_api.rs | 38 ++++++++++++++++++++++++ 3 files changed, 145 insertions(+) diff --git a/src/binding.cc b/src/binding.cc index f57b64c7..69140db0 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1502,6 +1502,38 @@ const v8::Array* v8__Map__As__Array(const v8::Map& self) { return local_to_ptr(self.AsArray()); } +const v8::Set* v8__Set__New(v8::Isolate* isolate) { + return local_to_ptr(v8::Set::New(isolate)); +} + +size_t v8__Set__Size(const v8::Set& self) { return self.Size(); } + +void v8__Set__Clear(const v8::Set& self) { + return ptr_to_local(&self)->Clear(); +} + +v8::Set* v8__Set__Add(const v8::Set& self, const v8::Context& context, + const v8::Value& key) { + return maybe_local_to_ptr( + ptr_to_local(&self)->Add(ptr_to_local(&context), ptr_to_local(&key))); +} + +MaybeBool v8__Set__Has(const v8::Set& self, const v8::Context& context, + const v8::Value& key) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Has(ptr_to_local(&context), ptr_to_local(&key))); +} + +MaybeBool v8__Set__Delete(const v8::Set& self, const v8::Context& context, + const v8::Value& key) { + return maybe_to_maybe_bool( + ptr_to_local(&self)->Delete(ptr_to_local(&context), ptr_to_local(&key))); +} + +const v8::Array* v8__Set__As__Array(const v8::Set& self) { + return local_to_ptr(self.AsArray()); +} + const v8::Number* v8__Number__New(v8::Isolate* isolate, double value) { return *v8::Number::New(isolate, value); } diff --git a/src/object.rs b/src/object.rs index 6d727ad1..83124f3c 100644 --- a/src/object.rs +++ b/src/object.rs @@ -19,6 +19,7 @@ use crate::Private; use crate::PropertyAttribute; use crate::PropertyDescriptor; use crate::PropertyFilter; +use crate::Set; use crate::String; use crate::Value; use std::convert::TryFrom; @@ -214,6 +215,25 @@ extern "C" { ) -> MaybeBool; fn v8__Map__Size(map: *const Map) -> usize; fn v8__Map__As__Array(this: *const Map) -> *const Array; + fn v8__Set__New(isolate: *mut Isolate) -> *const Set; + fn v8__Set__Clear(this: *const Set); + fn v8__Set__Add( + this: *const Set, + context: *const Context, + key: *const Value, + ) -> *const Set; + fn v8__Set__Has( + this: *const Set, + context: *const Context, + key: *const Value, + ) -> MaybeBool; + fn v8__Set__Delete( + this: *const Set, + context: *const Context, + key: *const Value, + ) -> MaybeBool; + fn v8__Set__Size(map: *const Set) -> usize; + fn v8__Set__As__Array(this: *const Set) -> *const Array; } impl Object { @@ -850,3 +870,58 @@ impl Map { unsafe { scope.cast_local(|_| v8__Map__As__Array(self)) }.unwrap() } } + +impl Set { + #[inline(always)] + pub fn new<'s>(scope: &mut HandleScope<'s>) -> Local<'s, Set> { + unsafe { scope.cast_local(|sd| v8__Set__New(sd.get_isolate_ptr())) } + .unwrap() + } + + #[inline(always)] + pub fn size(&self) -> usize { + unsafe { v8__Set__Size(self) } + } + + #[inline(always)] + pub fn clear(&self) { + unsafe { v8__Set__Clear(self) } + } + + #[inline(always)] + pub fn add<'s>( + &self, + scope: &mut HandleScope<'s>, + key: Local, + ) -> Option> { + unsafe { + scope.cast_local(|sd| v8__Set__Add(self, sd.get_current_context(), &*key)) + } + } + + #[inline(always)] + pub fn has( + &self, + scope: &mut HandleScope, + key: Local, + ) -> Option { + unsafe { v8__Set__Has(self, &*scope.get_current_context(), &*key) }.into() + } + + #[inline(always)] + pub fn delete( + &self, + scope: &mut HandleScope, + key: Local, + ) -> Option { + unsafe { v8__Set__Delete(self, &*scope.get_current_context(), &*key) } + .into() + } + + /// Returns an array of length size() * 2, where index N is the Nth key and + /// index N + 1 is the Nth value. + #[inline(always)] + pub fn as_array<'s>(&self, scope: &mut HandleScope<'s>) -> Local<'s, Array> { + unsafe { scope.cast_local(|_| v8__Set__As__Array(self)) }.unwrap() + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index 10d0349e..a8a5c641 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -2350,6 +2350,44 @@ fn map() { } } +#[test] +fn set() { + let _setup_guard = setup::parallel_test(); + let isolate = &mut v8::Isolate::new(Default::default()); + { + let scope = &mut v8::HandleScope::new(isolate); + let context = v8::Context::new(scope); + let scope = &mut v8::ContextScope::new(scope, context); + + let set = v8::Set::new(scope); + assert_eq!(set.size(), 0); + + { + let key = v8::Object::new(scope).into(); + assert_eq!(set.has(scope, key), Some(false)); + assert_eq!(set.add(scope, key), Some(set)); + + assert_eq!(set.has(scope, key), Some(true)); + assert_eq!(set.size(), 1); + } + + set.clear(); + assert_eq!(set.size(), 0); + + { + let key = v8::String::new(scope, "key").unwrap().into(); + + assert_eq!(set.delete(scope, key), Some(false)); + + set.add(scope, key); + assert_eq!(set.size(), 1); + + assert_eq!(set.delete(scope, key), Some(true)); + assert_eq!(set.size(), 0); + } + } +} + #[test] fn array() { let _setup_guard = setup::parallel_test();