1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::mem::size_of;
use std::mem::MaybeUninit;

use crate::Local;
use crate::Value;

extern "C" {
  fn v8__PropertyDescriptor__CONSTRUCT(out: *mut PropertyDescriptor);
  fn v8__PropertyDescriptor__CONSTRUCT__Get_Set(
    this: *const PropertyDescriptor,
    get: *const Value,
    set: *const Value,
  );
  fn v8__PropertyDescriptor__DESTRUCT(this: *mut PropertyDescriptor);
  fn v8__PropertyDescriptor__set_enumerable(
    this: *mut PropertyDescriptor,
    enumerable: bool,
  );
  fn v8__PropertyDescriptor__set_configurable(
    this: *mut PropertyDescriptor,
    configurable: bool,
  );
}

#[repr(transparent)]
pub struct PropertyDescriptor([usize; 1]);

const _: () = {
  assert!(
    size_of::<PropertyDescriptor>() == size_of::<usize>(),
    "PropertyDescriptor size is not 1 usize"
  );
};

impl Default for PropertyDescriptor {
  fn default() -> Self {
    Self::new()
  }
}

impl PropertyDescriptor {
  pub fn new() -> Self {
    let mut this = MaybeUninit::<Self>::uninit();
    unsafe {
      v8__PropertyDescriptor__CONSTRUCT(this.as_mut_ptr());
      this.assume_init()
    }
  }

  pub fn new_from_get_set(get: Local<Value>, set: Local<Value>) -> Self {
    let mut this = MaybeUninit::<Self>::uninit();
    unsafe {
      v8__PropertyDescriptor__CONSTRUCT__Get_Set(
        this.as_mut_ptr(),
        &*get,
        &*set,
      );
      this.assume_init()
    }
  }

  pub fn set_enumerable(&mut self, enumerable: bool) {
    unsafe { v8__PropertyDescriptor__set_enumerable(self, enumerable) }
  }

  pub fn set_configurable(&mut self, configurable: bool) {
    unsafe { v8__PropertyDescriptor__set_configurable(self, configurable) }
  }
}

impl Drop for PropertyDescriptor {
  fn drop(&mut self) {
    unsafe { v8__PropertyDescriptor__DESTRUCT(self) }
  }
}