From 3ba358e478dcf776bbc72ad29c11afe3f1179999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Haudebourg?= Date: Thu, 15 Oct 2020 16:33:05 +0200 Subject: [PATCH] Implement `IntoIterator` for `Object`. --- src/object.rs | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/object.rs b/src/object.rs index e2dfbb9..a766182 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,4 +1,4 @@ -use std::{ ptr, mem, str, slice, fmt }; +use std::{ ptr, mem, str, slice, vec, fmt }; use std::ops::{ Index, IndexMut, Deref }; use std::iter::FromIterator; @@ -176,6 +176,24 @@ impl Clone for Key { } } +impl From for String { + fn from(key: Key) -> String { + unsafe { + if key.len > KEY_BUF_LEN { + // Construct a `String` out of the `key_ptr`. Since the key is + // always allocated from a slice, the capacity is equal to length. + String::from_raw_parts( + key.ptr, + key.len, + key.len + ) + } else { + String::from_utf8_unchecked(key.buf[0..key.len].to_vec()) + } + } + } +} + #[derive(Clone)] struct Node { // String-esque key abstraction @@ -643,6 +661,45 @@ impl<'a> ExactSizeIterator for IterMut<'a> { } } +pub struct IntoIter { + inner: vec::IntoIter +} + +impl Iterator for IntoIter { + type Item = (String, JsonValue); + + #[inline(always)] + fn next(&mut self) -> Option { + self.inner.next().map(|node| (node.key.into(), node.value)) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline(always)] + fn next_back(&mut self) -> Option { + self.inner.next_back().map(|node| (node.key.into(), node.value)) + } +} + +impl ExactSizeIterator for IntoIter { + #[inline(always)] + fn len(&self) -> usize { + self.inner.len() + } +} + +impl IntoIterator for Object { + type Item = (String, JsonValue); + type IntoIter = IntoIter; + + #[inline(always)] + fn into_iter(self) -> IntoIter { + IntoIter { + inner: self.store.into_iter() + } + } +} + /// Implements indexing by `&str` to easily access object members: /// /// ## Example