use crate::data::OwnedDataRow as RowValue;
use crate::data::Timeframe;
use shape_ast::error::{Result, ShapeError};
impl super::ExecutionContext {
pub fn set_current_row(&mut self, index: usize) -> Result<()> {
self.current_row_index = index;
Ok(())
}
pub fn current_row_index(&self) -> usize {
self.current_row_index
}
pub fn get_current_row_index(&self) -> usize {
self.current_row_index
}
pub fn row_count(&self) -> usize {
if let Some(ref cache) = self.data_cache {
if let (Ok(id), Ok(timeframe)) = (self.get_current_id(), self.get_current_timeframe()) {
return cache.row_count(&id, &timeframe);
}
}
0
}
pub fn get_row_timestamp(&self, index: usize) -> Result<i64> {
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let timeframe = self.get_current_timeframe()?;
if let Some(row) = cache.get_row(&id, &timeframe, index) {
return Ok(row.timestamp);
}
}
Err(ShapeError::DataError {
message: format!("No timestamp available at index {}", index),
symbol: self.current_id.clone(),
timeframe: self.current_timeframe.as_ref().map(|t| t.to_string()),
})
}
pub fn get_row(&mut self, relative_index: i32) -> Result<RowValue> {
tracing::trace!("get_row called with relative_index: {}", relative_index);
if let Some(ref guard) = self.lookahead_guard {
guard.check_row_index(relative_index, "get_row")?;
}
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let timeframe = self.get_current_timeframe()?;
let absolute_index = (self.current_row_index as i32 + relative_index) as usize;
if let Some(row) = cache.get_row(&id, &timeframe, absolute_index) {
return Ok(row);
}
}
Err(ShapeError::DataError {
message: format!(
"No data available at index {}. Data must be prefetched before execution.",
relative_index
),
symbol: self.current_id.clone(), timeframe: self.current_timeframe.as_ref().map(|tf| tf.to_string()),
})
}
pub fn get_row_range(&mut self, start: i32, end: i32) -> Result<Vec<RowValue>> {
if let Some(ref guard) = self.lookahead_guard {
guard.check_row_index(start, "get_row_range_start")?;
guard.check_row_index(end, "get_row_range_end")?;
}
if start > end {
return Err(ShapeError::RuntimeError {
message: format!("Invalid row range: {} to {}", start, end),
location: None,
});
}
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let timeframe = self.get_current_timeframe()?;
let mut rows = Vec::new();
for i in start..=end {
let absolute_index = (self.current_row_index as i32 + i) as usize;
if let Some(row) = cache.get_row(&id, &timeframe, absolute_index) {
rows.push(row);
}
}
return Ok(rows);
}
Ok(Vec::new())
}
pub fn get_row_with_timeframe(
&mut self,
index: i32,
timeframe: &Timeframe,
) -> Result<RowValue> {
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let absolute_index = (self.current_row_index as i32 + index) as usize;
if let Some(row) = cache.get_row(&id, timeframe, absolute_index) {
return Ok(row);
}
}
Err(ShapeError::DataError {
message: format!(
"No data available for timeframe {} at index {}",
timeframe, index
),
symbol: self.current_id.clone(),
timeframe: Some(timeframe.to_string()),
})
}
pub fn get_row_range_with_timeframe(
&mut self,
start: i32,
end: i32,
timeframe: &Timeframe,
) -> Result<Vec<RowValue>> {
if start > end {
return Err(ShapeError::RuntimeError {
message: format!("Invalid row range: {} to {}", start, end),
location: None,
});
}
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let mut rows = Vec::new();
for i in start..=end {
let absolute_index = (self.current_row_index as i32 + i) as usize;
if let Some(row) = cache.get_row(&id, timeframe, absolute_index) {
rows.push(row);
}
}
return Ok(rows);
}
Ok(Vec::new())
}
pub fn get_row_relative_to_reference(&mut self, relative_index: i32) -> Result<RowValue> {
self.get_row(relative_index)
}
pub fn get_row_range_relative_to_reference(
&mut self,
start: i32,
end: i32,
) -> Result<Vec<RowValue>> {
self.get_row_range(start, end)
}
pub fn get_all_rows(&mut self) -> Result<Vec<RowValue>> {
if let Some(ref cache) = self.data_cache {
let id = self.get_current_id()?;
let timeframe = self.get_current_timeframe()?;
let count = cache.row_count(&id, &timeframe);
let mut rows = Vec::with_capacity(count);
for i in 0..count {
if let Some(row) = cache.get_row(&id, &timeframe, i) {
rows.push(row);
}
}
return Ok(rows);
}
Ok(Vec::new())
}
}