Add Stream support for field accessors
The type checker now correctly handles unwrapping `Stream(T)` types for lambda arguments. A new `build_map_stream` function has been added to `rtl/streams.rs` to facilitate field access on streams. The `create-random-ohlc` function now returns a `Stream` instead of a `Series`. Examples have been updated to reflect these changes and demonstrate stream usage.
This commit is contained in:
+37
-18
@@ -384,6 +384,12 @@ impl VM {
|
||||
field.name()
|
||||
));
|
||||
}
|
||||
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *field);
|
||||
return Ok(Value::Object(Rc::new(mapped)));
|
||||
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), *field);
|
||||
return Ok(Value::Object(Rc::new(mapped)));
|
||||
}
|
||||
|
||||
// Fallback if it's another type of object that is not a RecordSeries.
|
||||
@@ -550,26 +556,33 @@ impl VM {
|
||||
k,
|
||||
);
|
||||
return Ok(Value::Object(std::rc::Rc::new(view)));
|
||||
} else {
|
||||
} else {
|
||||
return Err(format!(
|
||||
"RecordSeries does not have field :{}",
|
||||
k.name()
|
||||
));
|
||||
}
|
||||
}
|
||||
return Err(format!(
|
||||
"Field accessor .{} expects a record or RecordSeries, got {}",
|
||||
k.name(),
|
||||
obj.type_name()
|
||||
));
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Field accessor .{} expects a record or RecordSeries, got {}",
|
||||
k.name(),
|
||||
rec
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), k);
|
||||
return Ok(Value::Object(Rc::new(mapped)));
|
||||
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), k);
|
||||
return Ok(Value::Object(Rc::new(mapped)));
|
||||
}
|
||||
return Err(format!(
|
||||
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",
|
||||
k.name(),
|
||||
obj.type_name()
|
||||
));
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",
|
||||
k.name(),
|
||||
rec
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
_ => {
|
||||
return Err(format!(
|
||||
"Tail call target is not a function: {}",
|
||||
@@ -621,16 +634,22 @@ impl VM {
|
||||
k.name()
|
||||
))
|
||||
}
|
||||
} else if let Some(sn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::StreamNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(sn.inner.clone(), *k);
|
||||
Ok(Value::Object(Rc::new(mapped)))
|
||||
} else if let Some(pn) = obj.as_any().downcast_ref::<crate::ast::rtl::streams::PipelineNode>() {
|
||||
let mapped = crate::ast::rtl::streams::build_map_stream(pn.stream.clone(), *k);
|
||||
Ok(Value::Object(Rc::new(mapped)))
|
||||
} else {
|
||||
Err(format!(
|
||||
"Field accessor .{} expects a record or RecordSeries, got {}",
|
||||
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",
|
||||
k.name(),
|
||||
obj.type_name()
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(format!(
|
||||
"Field accessor .{} expects a record or RecordSeries, got {}",
|
||||
"Field accessor .{} expects a record, RecordSeries or Stream, got {}",
|
||||
k.name(),
|
||||
rec
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user