Skip to content

Commit f7bdf7e

Browse files
authored
Improve docs around Val conversion in collections (#1774)
### What Improve documentation for Vec and Map to clarify that element types in host-backed collections are validated lazily — only when accessed — not when the collection is constructed or received as a contract argument. ### Why Val conversion / type guarantees were documented for both the `Vec` and `Map` structs, but was missing on some of the utility functions where validation was unclear.
1 parent 26a3616 commit f7bdf7e

3 files changed

Lines changed: 42 additions & 5 deletions

File tree

soroban-sdk/src/iter.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
//! Iterators for use with collections like [Map], [Vec].
2+
//!
3+
//! Collections are not guaranteed to contain values of the expected type as
4+
//! they are stored on the host as [Val]s, so two iterators are provided:
5+
//!
6+
//! - **`try_iter()`** returns an iterator that yields `Result<T, E>` for each
7+
//! element, allowing the caller to handle conversion errors.
8+
//! - **`iter()`** returns an iterator that unwraps each result,
9+
//! panicking if any element cannot be converted to the declared type.
210
#[cfg(doc)]
3-
use crate::{Map, Vec};
11+
use crate::{Map, Val, Vec};
412

513
use core::fmt::Debug;
614
use core::iter::FusedIterator;

soroban-sdk/src/map.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ macro_rules! map {
5353
/// converted from [Val] back into their type.
5454
///
5555
/// The pairs of keys and values in a Map are not guaranteed to be of type
56-
/// `K`/`V` and conversion will fail if they are not. Most functions on Map
57-
/// return a `Result` due to this.
56+
/// `K`/`V` and conversion will fail if they are not. Most functions on Map have
57+
/// a try_ variation that returns a Result that will be Err if the conversion fails.
58+
/// Functions that are not prefixed with try_ will panic if conversion fails."
5859
///
5960
/// There are some cases where this lack of guarantee is important:
6061
///
@@ -445,15 +446,23 @@ where
445446
self.obj = env.map_del(self.obj, k.into_val(env)).unwrap_infallible();
446447
}
447448

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

456-
/// Returns a [Vec] of all values in the map.
461+
/// Returns a [Vec] of all values in the map, ordered in the map's key-sorted order.
462+
///
463+
/// This method does not validate that the values in the map are of type `V`. Since [Map]
464+
/// values are not guaranteed to be of type `V`, it is not guaranteed that all values
465+
/// in the returned [Vec] will be of type `V`.
457466
#[inline(always)]
458467
pub fn values(&self) -> Vec<V> {
459468
let env = self.env();
@@ -495,6 +504,14 @@ where
495504
K: IntoVal<Env, Val> + TryFromVal<Env, Val>,
496505
V: IntoVal<Env, Val> + TryFromVal<Env, Val>,
497506
{
507+
/// Returns an iterator over the key-value pairs of the map.
508+
///
509+
/// Each entry is converted from [Val] to `(K, V)` as it is yielded.
510+
///
511+
/// ### Panics
512+
///
513+
/// If any key or value cannot be converted to its declared type.
514+
/// Use [`try_iter`](Map::try_iter) to handle conversion errors.
498515
#[inline(always)]
499516
pub fn iter(&self) -> UnwrappedIter<MapTryIter<K, V>, (K, V), ConversionError>
500517
where
@@ -504,6 +521,8 @@ where
504521
self.clone().into_iter()
505522
}
506523

524+
/// Returns an iterator over the key-value pairs of the map, yielding
525+
/// `Result<(K, V), ConversionError>` for each entry.
507526
#[inline(always)]
508527
pub fn try_iter(&self) -> MapTryIter<K, V>
509528
where

soroban-sdk/src/vec.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,14 @@ impl<T> Vec<T>
961961
where
962962
T: IntoVal<Env, Val> + TryFromVal<Env, Val>,
963963
{
964+
/// Returns an iterator over the elements of the vec.
965+
///
966+
/// Each element is converted from [Val] to `T` as it is yielded.
967+
///
968+
/// ### Panics
969+
///
970+
/// If any element cannot be converted to type `T`. Use
971+
/// [`try_iter`](Vec::try_iter) to handle conversion errors.
964972
#[inline(always)]
965973
pub fn iter(&self) -> UnwrappedIter<VecTryIter<T>, T, T::Error>
966974
where
@@ -970,6 +978,8 @@ where
970978
self.try_iter().unwrapped()
971979
}
972980

981+
/// Returns an iterator over the elements of the vec, yielding
982+
/// `Result<T, ConversionError>` for each element.
973983
#[inline(always)]
974984
pub fn try_iter(&self) -> VecTryIter<T>
975985
where

0 commit comments

Comments
 (0)