sim_lib_sequence/
runtime_iter.rs1use std::sync::Arc;
2
3use sim_kernel::{Cx, Error, Result, Value};
4
5use crate::{force_sequence_bounded, lazy_sequence_value};
6
7pub trait RuntimeIndexSource: Send + Sync {
13 fn value_at_runtime_index(&self, cx: &mut Cx, index: i64) -> Result<Option<Value>>;
15}
16
17pub struct RuntimeIndexLookup<F> {
19 lookup: F,
20}
21
22impl<F> RuntimeIndexLookup<F> {
23 pub fn new(lookup: F) -> Self {
25 Self { lookup }
26 }
27}
28
29impl<F> RuntimeIndexSource for RuntimeIndexLookup<F>
30where
31 F: Fn(&mut Cx, i64) -> Result<Option<Value>> + Send + Sync,
32{
33 fn value_at_runtime_index(&self, cx: &mut Cx, index: i64) -> Result<Option<Value>> {
34 (self.lookup)(cx, index)
35 }
36}
37
38pub fn runtime_index_sequence<S>(cx: &mut Cx, source: Arc<S>, first_index: i64) -> Result<Value>
43where
44 S: RuntimeIndexSource + 'static,
45{
46 lazy_sequence_value(
47 cx,
48 Arc::new(move |cx, offset| {
49 let offset = i64::try_from(offset)
50 .map_err(|_| Error::Eval("runtime index offset overflow".to_owned()))?;
51 let index = first_index
52 .checked_add(offset)
53 .ok_or_else(|| Error::Eval("runtime index overflow".to_owned()))?;
54 source.value_at_runtime_index(cx, index)
55 }),
56 )
57}
58
59pub fn runtime_index_lookup_sequence<F>(cx: &mut Cx, lookup: F, first_index: i64) -> Result<Value>
61where
62 F: Fn(&mut Cx, i64) -> Result<Option<Value>> + Send + Sync + 'static,
63{
64 runtime_index_sequence(cx, Arc::new(RuntimeIndexLookup::new(lookup)), first_index)
65}
66
67pub fn runtime_index_values<S>(
69 cx: &mut Cx,
70 source: Arc<S>,
71 first_index: i64,
72 max: usize,
73 context: &str,
74) -> Result<Vec<Value>>
75where
76 S: RuntimeIndexSource + 'static,
77{
78 let sequence = runtime_index_sequence(cx, source, first_index)?;
79 force_sequence_bounded(cx, &sequence, max, context)
80}