Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion soroban-sdk/src/iter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
//! Iterators for use with collections like [Map], [Vec].
//!
//! Collections are not guaranteed to contain values of the expected type as
//! they are stored on the host as [Val]s, so two iterators are provided:
Comment thread
mootz12 marked this conversation as resolved.
//!
//! - **`try_iter()`** returns an iterator that yields `Result<T, E>` for each
//! element, allowing the caller to handle conversion errors.
//! - **`iter()`** returns an iterator that unwraps each result,
//! panicking if any element cannot be converted to the declared type.
#[cfg(doc)]
use crate::{Map, Vec};
use crate::{Map, Val, Vec};

use core::fmt::Debug;
use core::iter::FusedIterator;
Expand Down
27 changes: 23 additions & 4 deletions soroban-sdk/src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ macro_rules! map {
/// converted from [Val] back into their type.
///
/// The pairs of keys and values in a Map are not guaranteed to be of type
/// `K`/`V` and conversion will fail if they are not. Most functions on Map
/// return a `Result` due to this.
/// `K`/`V` and conversion will fail if they are not. Most functions on Map have
/// a try_ variation that returns a Result that will be Err if the conversion fails.
/// Functions that are not prefixed with try_ will panic if conversion fails."
///
/// There are some cases where this lack of guarantee is important:
///
Expand Down Expand Up @@ -445,15 +446,23 @@ where
self.obj = env.map_del(self.obj, k.into_val(env)).unwrap_infallible();
}

/// Returns a [Vec] of all keys in the map.
/// Returns a [Vec] of all keys in the map, ordered in the map's key-sorted order.
///
/// This method does not validate that the keys in the map are of type `K`. Since [Map]
/// keys are not guaranteed to be of type `K`, it is not guaranteed that all values
/// in the returned [Vec] will be of type `K`.
#[inline(always)]
pub fn keys(&self) -> Vec<K> {
let env = self.env();
let vec = env.map_keys(self.obj).unwrap_infallible();
Vec::<K>::try_from_val(env, &vec).unwrap()
}

/// Returns a [Vec] of all values in the map.
/// Returns a [Vec] of all values in the map, ordered in the map's key-sorted order.
///
/// This method does not validate that the values in the map are of type `V`. Since [Map]
/// values are not guaranteed to be of type `V`, it is not guaranteed that all values
/// in the returned [Vec] will be of type `V`.
#[inline(always)]
pub fn values(&self) -> Vec<V> {
let env = self.env();
Expand Down Expand Up @@ -495,6 +504,14 @@ where
K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
{
/// Returns an iterator over the key-value pairs of the map.
///
/// Each entry is converted from [Val] to `(K, V)` as it is yielded.
///
/// ### Panics
///
/// If any key or value cannot be converted to its declared type.
/// Use [`try_iter`](Map::try_iter) to handle conversion errors.
#[inline(always)]
pub fn iter(&self) -> UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>
where
Expand All @@ -504,6 +521,8 @@ where
self.clone().into_iter()
}

/// Returns an iterator over the key-value pairs of the map, yielding
/// `Result<(K, V), ConversionError>` for each entry.
#[inline(always)]
pub fn try_iter(&self) -> MapTryIter<K, V>
where
Expand Down
10 changes: 10 additions & 0 deletions soroban-sdk/src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,14 @@ impl<T> Vec<T>
where
T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
{
/// Returns an iterator over the elements of the vec.
///
/// Each element is converted from [Val] to `T` as it is yielded.
///
/// ### Panics
///
/// If any element cannot be converted to type `T`. Use
/// [`try_iter`](Vec::try_iter) to handle conversion errors.
#[inline(always)]
pub fn iter(&self) -> UnwrappedIter<VecTryIter<T>, T, T::Error>
where
Expand All @@ -970,6 +978,8 @@ where
self.try_iter().unwrapped()
}

/// Returns an iterator over the elements of the vec, yielding
/// `Result<T, ConversionError>` for each element.
Comment thread
mootz12 marked this conversation as resolved.
#[inline(always)]
pub fn try_iter(&self) -> VecTryIter<T>
where
Expand Down
Loading