values.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. use std::pin::Pin;
  5. use crate::rs_glue;
  6. /// A reference to a C++ `base::Value` of type `base::Value::Type::DICTIONARY`.
  7. /// Such a value is currently either held directly in a populated
  8. /// [`ValueSlotRef`] or in a child `base::Value` thereof.
  9. pub struct DictValueRef<'a>(Pin<&'a mut rs_glue::ffi::Value>);
  10. impl<'a> DictValueRef<'a> {
  11. /// Get a reference to the base::Value.
  12. fn raw_mut(&mut self) -> Pin<&mut rs_glue::ffi::Value> {
  13. self.0.as_mut()
  14. }
  15. /// Sets the value at this dictionary key to be a value of type
  16. /// `base::Value::Type::NONE`.
  17. pub fn set_none_key(&mut self, key: &str) {
  18. rs_glue::ffi::ValueSetNoneKey(self.raw_mut(), key);
  19. }
  20. /// Sets the value at this dictionary key to a Boolean.
  21. pub fn set_bool_key(&mut self, key: &str, val: bool) {
  22. rs_glue::ffi::ValueSetBoolKey(self.raw_mut(), key, val);
  23. }
  24. /// Sets the value at this dictionary key to an integer.
  25. pub fn set_integer_key(&mut self, key: &str, val: i32) {
  26. rs_glue::ffi::ValueSetIntegerKey(self.raw_mut(), key, val);
  27. }
  28. /// Sets the value at this dictionary key to a double.
  29. pub fn set_double_key(&mut self, key: &str, val: f64) {
  30. rs_glue::ffi::ValueSetDoubleKey(self.raw_mut(), key, val);
  31. }
  32. /// Sets the value at this dictionary key to a string.
  33. pub fn set_string_key(&mut self, key: &str, val: &str) {
  34. rs_glue::ffi::ValueSetStringKey(self.raw_mut(), key, val);
  35. }
  36. /// Sets the value at this dictionary key to a new dictionary, and returns
  37. /// a reference to it.
  38. pub fn set_dict_key(&mut self, key: &str) -> DictValueRef {
  39. rs_glue::ffi::ValueSetDictKey(self.raw_mut(), key).into()
  40. }
  41. /// Sets the value at this dictionary key to a new list, and returns a
  42. /// reference to it.
  43. pub fn set_list_key(&mut self, key: &str) -> ListValueRef {
  44. rs_glue::ffi::ValueSetListKey(self.raw_mut(), key).into()
  45. }
  46. }
  47. impl<'a> From<Pin<&'a mut rs_glue::ffi::Value>> for DictValueRef<'a> {
  48. /// Wrap a reference to a C++ `base::Value` in a newtype wrapper to
  49. /// indicate that it's of type DICTIONARY. This is not actually unsafe,
  50. /// since any mistakes here will result in a deliberate crash due to
  51. /// assertions on the C++ side, rather than memory safety errors.
  52. fn from(value: Pin<&'a mut rs_glue::ffi::Value>) -> Self {
  53. Self(value)
  54. }
  55. }
  56. /// A reference to a C++ `base::Value` of type `base::Value::Type::LIST`.
  57. /// Such a value is currently either held directly in a populated
  58. /// [`ValueSlotRef`] or in a child `base::Value` thereof.
  59. pub struct ListValueRef<'a>(Pin<&'a mut rs_glue::ffi::Value>);
  60. impl<'a> ListValueRef<'a> {
  61. /// Get a reference to the underlying base::Value.
  62. fn raw_mut(&mut self) -> Pin<&mut rs_glue::ffi::Value> {
  63. self.0.as_mut()
  64. }
  65. /// Appends a value of type `base::Value::Type::NONE`. Grows
  66. /// the list as necessary.
  67. pub fn append_none(&mut self) {
  68. rs_glue::ffi::ValueAppendNone(self.raw_mut());
  69. }
  70. /// Appends a Boolean. Grows the list as necessary.
  71. pub fn append_bool(&mut self, val: bool) {
  72. self.raw_mut().ValueAppendBool(val)
  73. }
  74. /// Appends an integer. Grows the list as necessary.
  75. pub fn append_integer(&mut self, val: i32) {
  76. self.raw_mut().ValueAppendInteger(val)
  77. }
  78. /// Appends a double. Grows the list as necessary.
  79. pub fn append_double(&mut self, val: f64) {
  80. self.raw_mut().ValueAppendDouble(val)
  81. }
  82. /// Appends a string. Grows the list as necessary.
  83. pub fn append_string(&mut self, val: &str) {
  84. rs_glue::ffi::ValueAppendString(self.raw_mut(), val);
  85. }
  86. /// Appends a new dictionary, and returns a reference to it.
  87. /// Grows the list as necessary.
  88. pub fn append_dict(&mut self) -> DictValueRef {
  89. rs_glue::ffi::ValueAppendDict(self.raw_mut()).into()
  90. }
  91. /// Appends a new list, and returns a reference to it. Grows
  92. /// the list as necessary.
  93. pub fn append_list(&mut self) -> ListValueRef {
  94. rs_glue::ffi::ValueAppendList(self.raw_mut()).into()
  95. }
  96. /// Reserves space for a given number of elements within a list. This is
  97. /// optional - lists will grow as necessary to accommodate the items you
  98. /// add, so this just reduces the allocations necessary.
  99. pub fn reserve_size(&mut self, len: usize) {
  100. rs_glue::ffi::ValueReserveSize(self.raw_mut(), len);
  101. }
  102. }
  103. impl<'a> From<Pin<&'a mut rs_glue::ffi::Value>> for ListValueRef<'a> {
  104. /// Wrap a reference to a C++ `base::Value` in a newtype wrapper to
  105. /// indicate that it's of type LIST. This is not actually unsafe, since
  106. /// any mistakes here will result in a deliberate crash due to assertions
  107. /// on the C++ side, rather than memory safety errors.
  108. fn from(value: Pin<&'a mut rs_glue::ffi::Value>) -> Self {
  109. Self(value)
  110. }
  111. }
  112. /// A reference to a slot in which a `base::Value` can be constructed.
  113. /// Such a slot can only be created within C++ and passed to Rust; Rust
  114. /// can then create a `base::Value` therein.
  115. pub struct ValueSlotRef<'a>(Pin<&'a mut rs_glue::ffi::ValueSlot>);
  116. impl<'a> From<Pin<&'a mut rs_glue::ffi::ValueSlot>> for ValueSlotRef<'a> {
  117. fn from(value: Pin<&'a mut rs_glue::ffi::ValueSlot>) -> Self {
  118. Self(value)
  119. }
  120. }
  121. impl<'a> From<&'a mut cxx::UniquePtr<rs_glue::ffi::ValueSlot>> for ValueSlotRef<'a> {
  122. fn from(value: &'a mut cxx::UniquePtr<rs_glue::ffi::ValueSlot>) -> Self {
  123. Self(value.pin_mut())
  124. }
  125. }
  126. impl<'a> ValueSlotRef<'a> {
  127. /// Return a mutable reference to the underlying raw value.
  128. fn raw_mut(&mut self) -> Pin<&mut rs_glue::ffi::ValueSlot> {
  129. self.0.as_mut()
  130. }
  131. /// Return a reference to the underlying raw value.
  132. fn raw(&self) -> &rs_glue::ffi::ValueSlot {
  133. &self.0
  134. }
  135. /// Creates a new `base::Value::Type::NONE` `base::Value` in this slot.
  136. pub fn construct_none(&mut self) {
  137. rs_glue::ffi::ConstructNoneValue(self.raw_mut());
  138. }
  139. /// Creates a new Boolean `base::Value` in this slot.
  140. pub fn construct_bool(&mut self, val: bool) {
  141. rs_glue::ffi::ConstructBoolValue(self.raw_mut(), val);
  142. }
  143. /// Creates a new integer `base::Value` in this slot.
  144. pub fn construct_integer(&mut self, val: i32) {
  145. rs_glue::ffi::ConstructIntegerValue(self.raw_mut(), val);
  146. }
  147. /// Creates a new double `base::Value` in this slot.
  148. pub fn construct_double(&mut self, val: f64) {
  149. rs_glue::ffi::ConstructDoubleValue(self.raw_mut(), val);
  150. }
  151. /// Creates a new string `base::Value` in this slot.
  152. pub fn construct_string(&mut self, val: &str) {
  153. rs_glue::ffi::ConstructStringValue(self.raw_mut(), val);
  154. }
  155. /// Creates a new dictionary `base::Value` in this slot.
  156. pub fn construct_dict(&mut self) -> DictValueRef {
  157. rs_glue::ffi::ConstructDictValue(self.raw_mut()).into()
  158. }
  159. /// Creates a new list `base::Value` in this slot.
  160. pub fn construct_list(&mut self) -> ListValueRef {
  161. rs_glue::ffi::ConstructListValue(self.raw_mut()).into()
  162. }
  163. }
  164. /// Asks C++ code to dump this base::Value back to JSON.
  165. /// Primarily for testing the round-trip.
  166. impl<'a> std::fmt::Debug for ValueSlotRef<'a> {
  167. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
  168. f.write_str(&rs_glue::ffi::DumpValueSlot(self.raw()))
  169. }
  170. }