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
18pub type IntoIter = hash_map::IntoIter<String, Value>;
26
27pub type IterMut<'a> = hash_map::IterMut<'a, String, Value>;
35
36pub type Iter<'a> = hash_map::Iter<'a, String, Value>;
44
45pub type Keys<'a> = hash_map::Keys<'a, String, Value>;
53
54pub type Values<'a> = hash_map::Values<'a, String, Value>;
62
63#[derive(Any, Default)]
83#[repr(transparent)]
84#[rune(item = ::std::object)]
85pub struct Object {
86 inner: FieldMap<String, Value>,
87}
88
89impl Object {
90 #[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 #[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 #[inline]
132 #[rune::function(keep)]
133 pub fn len(&self) -> usize {
134 self.inner.len()
135 }
136
137 #[inline]
148 #[rune::function(keep)]
149 pub fn is_empty(&self) -> bool {
150 self.inner.is_empty()
151 }
152
153 #[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 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 #[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 #[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 #[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 #[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 #[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 #[inline]
244 #[rune::function(keep)]
245 pub fn clear(&mut self) {
246 self.inner.clear();
247 }
248
249 pub fn iter(&self) -> Iter<'_> {
252 self.inner.iter()
253 }
254
255 pub fn keys(&self) -> Keys<'_> {
258 self.inner.keys()
259 }
260
261 pub fn values(&self) -> Values<'_> {
264 self.inner.values()
265 }
266
267 pub fn iter_mut(&mut self) -> IterMut<'_> {
272 self.inner.iter_mut()
273 }
274
275 #[rune::function(keep, path = Self::iter)]
291 pub fn rune_iter(this: Ref<Self>) -> RuneIter {
292 let iter = unsafe { this.inner.raw_table().iter() };
295 let (_, guard) = Ref::into_raw(this);
296 RuneIter { iter, guard }
297 }
298
299 #[rune::function(keep, path = Self::keys)]
315 pub fn rune_keys(this: Ref<Self>) -> RuneIterKeys {
316 let iter = unsafe { this.inner.raw_table().iter() };
319 let (_, guard) = Ref::into_raw(this);
320 RuneIterKeys { iter, guard }
321 }
322
323 #[rune::function(keep, path = Self::values)]
339 pub fn rune_values(this: Ref<Self>) -> RuneValues {
340 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 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}