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