rune/runtime/
object.rs

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