rune/runtime/
object.rs

1use core::borrow;
2use core::cmp;
3use core::fmt;
4use core::hash;
5use core::iter;
6
7use crate as rune;
8use crate::alloc::hash_map;
9use crate::alloc::hashbrown::raw::RawIter;
10use crate::alloc::prelude::*;
11use crate::alloc::{self, String};
12use crate::runtime::{
13    FieldMap, FromValue, ProtocolCaller, RawAnyGuard, Ref, ToValue, Value, VmError, VmResult,
14};
15use crate::Any;
16
17/// An owning iterator over the entries of a `Object`.
18///
19/// This `struct` is created by the [`into_iter`] method on [`Object`]
20/// (provided by the `IntoIterator` trait). See its documentation for more.
21///
22/// [`into_iter`]: struct.Object.html#method.into_iter
23/// [`Object`]: struct.Object.html
24pub type IntoIter = hash_map::IntoIter<String, Value>;
25
26/// A mutable iterator over the entries of a `Object`.
27///
28/// This `struct` is created by the [`iter_mut`] method on [`Object`]. See its
29/// documentation for more.
30///
31/// [`iter_mut`]: struct.Object.html#method.iter_mut
32/// [`Object`]: struct.Object.html
33pub type IterMut<'a> = hash_map::IterMut<'a, String, Value>;
34
35/// An iterator over the entries of a `Object`.
36///
37/// This `struct` is created by the [`iter`] method on [`Object`]. See its
38/// documentation for more.
39///
40/// [`iter`]: struct.Object.html#method.iter
41/// [`Object`]: struct.Object.html
42pub type Iter<'a> = hash_map::Iter<'a, String, Value>;
43
44/// An iterator over the keys of a `HashMap`.
45///
46/// This `struct` is created by the [`keys`] method on [`Object`]. See its
47/// documentation for more.
48///
49/// [`keys`]: struct.Object.html#method.keys
50/// [`Object`]: struct.Object.html
51pub type Keys<'a> = hash_map::Keys<'a, String, Value>;
52
53/// An iterator over the values of a `HashMap`.
54///
55/// This `struct` is created by the [`values`] method on [`Object`]. See its
56/// documentation for more.
57///
58/// [`values`]: struct.Object.html#method.values
59/// [`Object`]: struct.Object.html
60pub type Values<'a> = hash_map::Values<'a, String, Value>;
61
62/// Struct representing a dynamic anonymous object.
63///
64/// # Rust Examples
65///
66/// ```rust
67/// use rune::alloc::String;
68///
69/// let mut object = rune::runtime::Object::new();
70/// assert!(object.is_empty());
71///
72/// object.insert_value(String::try_from("foo")?, 42).into_result()?;
73/// object.insert_value(String::try_from("bar")?, true).into_result()?;
74/// assert_eq!(2, object.len());
75///
76/// assert_eq!(Some(42), object.get_value("foo").into_result()?);
77/// assert_eq!(Some(true), object.get_value("bar").into_result()?);
78/// assert_eq!(None::<bool>, object.get_value("baz").into_result()?);
79/// # Ok::<_, rune::support::Error>(())
80/// ```
81#[derive(Any, Default)]
82#[repr(transparent)]
83#[rune(item = ::std::object)]
84pub struct Object {
85    inner: FieldMap<String, Value>,
86}
87
88impl Object {
89    /// Construct a new object.
90    ///
91    /// # Examples
92    ///
93    /// ```rune
94    /// let object = Object::new();
95    /// object.insert("Hello", "World");
96    /// ```
97    #[inline]
98    #[rune::function(keep, path = Self::new)]
99    pub fn new() -> Self {
100        Self {
101            inner: crate::runtime::new_field_map(),
102        }
103    }
104
105    /// Construct a new object with the given capacity.
106    ///
107    /// # Examples
108    ///
109    /// ```rune
110    /// let object = Object::with_capacity(16);
111    /// object.insert("Hello", "World");
112    /// ```
113    #[inline]
114    #[rune::function(path = Self::with_capacity)]
115    pub(crate) fn rune_with_capacity(capacity: usize) -> VmResult<Self> {
116        VmResult::Ok(vm_try!(Self::with_capacity(capacity)))
117    }
118
119    /// Construct a new object with the given capacity.
120    pub fn with_capacity(capacity: usize) -> alloc::Result<Self> {
121        // BTreeMap doesn't support setting capacity on creation but we keep
122        // this here in case we want to switch store later.
123        Ok(Self {
124            inner: crate::runtime::new_field_hash_map_with_capacity(capacity)?,
125        })
126    }
127
128    /// Returns the number of elements in the object.
129    ///
130    /// # Examples
131    ///
132    /// ```rune
133    /// let object = Object::with_capacity(16);
134    /// object.insert("Hello", "World");
135    /// assert_eq!(object.len(), 1);
136    /// ```
137    #[inline]
138    #[rune::function(keep)]
139    pub fn len(&self) -> usize {
140        self.inner.len()
141    }
142
143    /// Returns `true` if the object is empty.
144    ///
145    /// # Examples
146    ///
147    /// ```rune
148    /// let object = Object::with_capacity(16);
149    /// assert!(object.is_empty());
150    /// object.insert("Hello", "World");
151    /// assert!(!object.is_empty());
152    /// ```
153    #[inline]
154    #[rune::function(keep)]
155    pub fn is_empty(&self) -> bool {
156        self.inner.is_empty()
157    }
158
159    /// Returns a reference to the value corresponding to the key.
160    #[inline]
161    pub fn get<Q>(&self, k: &Q) -> Option<&Value>
162    where
163        String: borrow::Borrow<Q>,
164        Q: ?Sized + hash::Hash + cmp::Eq + cmp::Ord,
165    {
166        self.inner.get(k)
167    }
168
169    /// Get the given value at the given index.
170    pub fn get_value<Q, T>(&self, k: &Q) -> VmResult<Option<T>>
171    where
172        String: borrow::Borrow<Q>,
173        Q: ?Sized + hash::Hash + cmp::Eq + cmp::Ord,
174        T: FromValue,
175    {
176        let value = match self.inner.get(k) {
177            Some(value) => value.clone(),
178            None => return VmResult::Ok(None),
179        };
180
181        VmResult::Ok(Some(vm_try!(T::from_value(value))))
182    }
183
184    /// Returns a mutable reference to the value corresponding to the key.
185    #[inline]
186    pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut Value>
187    where
188        String: borrow::Borrow<Q>,
189        Q: ?Sized + hash::Hash + cmp::Eq + cmp::Ord,
190    {
191        self.inner.get_mut(k)
192    }
193
194    /// Returns `true` if the map contains a value for the specified key.
195    #[inline]
196    pub fn contains_key<Q>(&self, k: &Q) -> bool
197    where
198        String: borrow::Borrow<Q>,
199        Q: ?Sized + hash::Hash + cmp::Eq + cmp::Ord,
200    {
201        self.inner.contains_key(k)
202    }
203
204    /// Removes a key from the map, returning the value at the key if the key
205    /// was previously in the map.
206    #[inline]
207    pub fn remove<Q>(&mut self, k: &Q) -> Option<Value>
208    where
209        String: borrow::Borrow<Q>,
210        Q: ?Sized + hash::Hash + cmp::Eq + cmp::Ord,
211    {
212        self.inner.remove(k)
213    }
214
215    /// Inserts a key-value pair into the dynamic object, converting it as
216    /// necessary through the [`ToValue`] trait.
217    #[inline]
218    pub fn insert_value<T>(&mut self, k: String, v: T) -> VmResult<()>
219    where
220        T: ToValue,
221    {
222        vm_try!(self.inner.try_insert(k, vm_try!(v.to_value())));
223        VmResult::Ok(())
224    }
225
226    /// Inserts a key-value pair into the map.
227    ///
228    /// If the map did not have this key present, `None` is returned.
229    ///
230    /// # Examples
231    ///
232    /// ```rune
233    /// let map = #{};
234    /// assert_eq!(map.insert("a", 1), None);
235    /// assert_eq!(map.is_empty(), false);
236    ///
237    /// map.insert("b", 2);
238    /// assert_eq!(map.insert("b", 3), Some(2));
239    /// assert_eq!(map["b"], 3);
240    /// ```
241    #[inline]
242    #[rune::function(path = Self::insert)]
243    pub(crate) fn rune_insert(&mut self, k: String, v: Value) -> VmResult<Option<Value>> {
244        VmResult::Ok(vm_try!(self.inner.try_insert(k, v)))
245    }
246
247    /// Inserts a key-value pair into the map.
248    ///
249    /// If the map did not have this key present, `None` is returned.
250    #[inline]
251    pub fn insert(&mut self, k: String, v: Value) -> alloc::Result<Option<Value>> {
252        self.inner.try_insert(k, v)
253    }
254
255    /// Clears the object, removing all key-value pairs. Keeps the allocated
256    /// memory for reuse.
257    #[inline]
258    #[rune::function(keep)]
259    pub fn clear(&mut self) {
260        self.inner.clear();
261    }
262
263    /// An iterator visiting all key-value pairs in arbitrary order.
264    /// The iterator element type is `(&'a String, &'a Value)`.
265    pub fn iter(&self) -> Iter<'_> {
266        self.inner.iter()
267    }
268
269    /// An iterator visiting all keys in arbitrary order.
270    /// The iterator element type is `&'a String`.
271    pub fn keys(&self) -> Keys<'_> {
272        self.inner.keys()
273    }
274
275    /// An iterator visiting all values in arbitrary order.
276    /// The iterator element type is `&'a Value`.
277    pub fn values(&self) -> Values<'_> {
278        self.inner.values()
279    }
280
281    /// An iterator visiting all key-value pairs in arbitrary order,
282    /// with mutable references to the values.
283    ///
284    /// The iterator element type is `(&'a String, &'a mut Value)`.
285    pub fn iter_mut(&mut self) -> IterMut<'_> {
286        self.inner.iter_mut()
287    }
288
289    /// An iterator visiting all keys and values in arbitrary order.
290    ///
291    /// # Examples
292    ///
293    /// ```rune
294    /// let object = #{a: 1, b: 2, c: 3};
295    /// let vec = [];
296    ///
297    /// for key in object.iter() {
298    ///     vec.push(key);
299    /// }
300    ///
301    /// vec.sort_by(|a, b| a.0.cmp(b.0));
302    /// assert_eq!(vec, [("a", 1), ("b", 2), ("c", 3)]);
303    /// ```
304    #[rune::function(keep, path = Self::iter)]
305    pub fn rune_iter(this: Ref<Self>) -> RuneIter {
306        // SAFETY: we're holding onto the related reference guard, and making
307        // sure that it's dropped after the iterator.
308        let iter = unsafe { this.inner.raw_table().iter() };
309        let (_, guard) = Ref::into_raw(this);
310        RuneIter { iter, guard }
311    }
312
313    /// An iterator visiting all keys in arbitrary order.
314    ///
315    /// # Examples
316    ///
317    /// ```rune
318    /// let object = #{a: 1, b: 2, c: 3};
319    /// let vec = [];
320    ///
321    /// for key in object.keys() {
322    ///     vec.push(key);
323    /// }
324    ///
325    /// vec.sort_by(|a, b| a.cmp(b));
326    /// assert_eq!(vec, ["a", "b", "c"]);
327    /// ```
328    #[rune::function(keep, path = Self::keys)]
329    pub fn rune_keys(this: Ref<Self>) -> RuneIterKeys {
330        // SAFETY: we're holding onto the related reference guard, and making
331        // sure that it's dropped after the iterator.
332        let iter = unsafe { this.inner.raw_table().iter() };
333        let (_, guard) = Ref::into_raw(this);
334        RuneIterKeys { iter, guard }
335    }
336
337    /// An iterator visiting all values in arbitrary order.
338    ///
339    /// # Examples
340    ///
341    /// ```rune
342    /// let object = #{a: 1, b: 2, c: 3};
343    /// let vec = [];
344    ///
345    /// for key in object.values() {
346    ///     vec.push(key);
347    /// }
348    ///
349    /// vec.sort_by(|a, b| a.cmp(b));
350    /// assert_eq!(vec, [1, 2, 3]);
351    /// ```
352    #[rune::function(keep, path = Self::values)]
353    pub fn rune_values(this: Ref<Self>) -> RuneValues {
354        // SAFETY: we're holding onto the related reference guard, and making
355        // sure that it's dropped after the iterator.
356        let iter = unsafe { this.inner.raw_table().iter() };
357        let (_, guard) = Ref::into_raw(this);
358        RuneValues { iter, guard }
359    }
360
361    pub(crate) fn partial_eq_with(
362        a: &Self,
363        b: &Self,
364        caller: &mut dyn ProtocolCaller,
365    ) -> VmResult<bool> {
366        if a.len() != b.len() {
367            return VmResult::Ok(false);
368        }
369
370        for (k1, v1) in a.iter() {
371            let Some(v2) = b.get(k1) else {
372                return VmResult::Ok(false);
373            };
374
375            if !vm_try!(Value::partial_eq_with(v1, v2, caller)) {
376                return VmResult::Ok(false);
377            }
378        }
379
380        VmResult::Ok(true)
381    }
382
383    pub(crate) fn eq_with(
384        a: &Self,
385        b: &Self,
386        eq: fn(&Value, &Value, &mut dyn ProtocolCaller) -> VmResult<bool>,
387        caller: &mut dyn ProtocolCaller,
388    ) -> VmResult<bool> {
389        if a.inner.len() != b.inner.len() {
390            return VmResult::Ok(false);
391        }
392
393        for (key, a) in a.inner.iter() {
394            let Some(b) = b.inner.get(key) else {
395                return VmResult::Ok(false);
396            };
397
398            if !vm_try!(eq(a, b, caller)) {
399                return VmResult::Ok(false);
400            }
401        }
402
403        VmResult::Ok(true)
404    }
405}
406
407impl TryClone for Object {
408    fn try_clone(&self) -> alloc::Result<Self> {
409        Ok(Self {
410            inner: self.inner.try_clone()?,
411        })
412    }
413}
414
415impl<'a> IntoIterator for &'a Object {
416    type Item = (&'a String, &'a Value);
417    type IntoIter = Iter<'a>;
418
419    fn into_iter(self) -> Self::IntoIter {
420        self.iter()
421    }
422}
423
424impl<'a> IntoIterator for &'a mut Object {
425    type Item = (&'a String, &'a mut Value);
426    type IntoIter = IterMut<'a>;
427
428    fn into_iter(self) -> Self::IntoIter {
429        self.iter_mut()
430    }
431}
432
433impl IntoIterator for Object {
434    type Item = (String, Value);
435    type IntoIter = IntoIter;
436
437    /// Creates a consuming iterator, that is, one that moves each key-value
438    /// pair out of the object in arbitrary order. The object cannot be used
439    /// after calling this.
440    fn into_iter(self) -> Self::IntoIter {
441        self.inner.into_iter()
442    }
443}
444
445impl fmt::Debug for Object {
446    #[inline]
447    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
448        f.debug_map().entries(self.inner.iter()).finish()
449    }
450}
451
452#[derive(Any)]
453#[rune(item = ::std::object, name = Iter)]
454pub struct RuneIter {
455    iter: RawIter<(String, Value)>,
456    #[allow(unused)]
457    guard: RawAnyGuard,
458}
459
460impl RuneIter {
461    #[rune::function(instance, keep, protocol = NEXT)]
462    pub fn next(&mut self) -> VmResult<Option<(String, Value)>> {
463        unsafe {
464            let Some(bucket) = self.iter.next() else {
465                return VmResult::Ok(None);
466            };
467
468            let (key, value) = bucket.as_ref();
469            let key = vm_try!(key.try_clone());
470            VmResult::Ok(Some((key, value.clone())))
471        }
472    }
473
474    #[rune::function(instance, keep, protocol = SIZE_HINT)]
475    pub fn size_hint(&self) -> (usize, Option<usize>) {
476        self.iter.size_hint()
477    }
478
479    #[rune::function(instance, keep, protocol = LEN)]
480    pub fn len(&self) -> usize {
481        self.iter.len()
482    }
483}
484
485impl iter::Iterator for RuneIter {
486    type Item = Result<(String, Value), VmError>;
487
488    #[inline]
489    fn next(&mut self) -> Option<Self::Item> {
490        match RuneIter::next(self) {
491            VmResult::Ok(Some(value)) => Some(Ok(value)),
492            VmResult::Ok(None) => None,
493            VmResult::Err(err) => Some(Err(err)),
494        }
495    }
496}
497
498#[derive(Any)]
499#[rune(item = ::std::object, name = Keys)]
500pub struct RuneIterKeys {
501    iter: RawIter<(String, Value)>,
502    #[allow(unused)]
503    guard: RawAnyGuard,
504}
505
506impl RuneIterKeys {
507    #[rune::function(instance, keep, protocol = NEXT)]
508    pub fn next(&mut self) -> VmResult<Option<String>> {
509        unsafe {
510            let Some(bucket) = self.iter.next() else {
511                return VmResult::Ok(None);
512            };
513
514            let (key, _) = bucket.as_ref();
515            let key = vm_try!(key.try_clone());
516            VmResult::Ok(Some(key))
517        }
518    }
519
520    #[rune::function(instance, keep, protocol = SIZE_HINT)]
521    pub fn size_hint(&self) -> (usize, Option<usize>) {
522        self.iter.size_hint()
523    }
524
525    #[rune::function(instance, keep, protocol = LEN)]
526    pub fn len(&self) -> usize {
527        self.iter.len()
528    }
529}
530
531impl iter::Iterator for RuneIterKeys {
532    type Item = Result<String, VmError>;
533
534    #[inline]
535    fn next(&mut self) -> Option<Self::Item> {
536        match RuneIterKeys::next(self) {
537            VmResult::Ok(Some(value)) => Some(Ok(value)),
538            VmResult::Ok(None) => None,
539            VmResult::Err(err) => Some(Err(err)),
540        }
541    }
542}
543
544#[derive(Any)]
545#[rune(item = ::std::object, name = Values)]
546pub struct RuneValues {
547    iter: RawIter<(String, Value)>,
548    #[allow(unused)]
549    guard: RawAnyGuard,
550}
551
552impl RuneValues {
553    #[rune::function(instance, keep, protocol = NEXT)]
554    pub fn next(&mut self) -> VmResult<Option<Value>> {
555        unsafe {
556            let Some(bucket) = self.iter.next() else {
557                return VmResult::Ok(None);
558            };
559
560            let (_, value) = bucket.as_ref();
561            VmResult::Ok(Some(value.clone()))
562        }
563    }
564
565    #[rune::function(instance, keep, protocol = SIZE_HINT)]
566    pub fn size_hint(&self) -> (usize, Option<usize>) {
567        self.iter.size_hint()
568    }
569
570    #[rune::function(instance, keep, protocol = LEN)]
571    pub fn len(&self) -> usize {
572        self.iter.len()
573    }
574}
575
576impl iter::Iterator for RuneValues {
577    type Item = Result<Value, VmError>;
578
579    #[inline]
580    fn next(&mut self) -> Option<Self::Item> {
581        match RuneValues::next(self) {
582            VmResult::Ok(Some(value)) => Some(Ok(value)),
583            VmResult::Ok(None) => None,
584            VmResult::Err(err) => Some(Err(err)),
585        }
586    }
587}