use super::event_merge_timing::EventTimer;
use super::event_toggle_effect::{EventEffector, EventToggler};
use super::{EventInfo, EventQuery, EventSortOptions, OwnedEvent};
use crate::core::errors::EditorError;
use crate::core::{Position, Range, Result};
use ass_core::parser::ast::{Event, Section};
use core::cmp::Ordering;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
impl<'a> EventQuery<'a> {
pub fn execute(self) -> Result<Vec<EventInfo>> {
let mut results = self.collect_events()?;
results = self.apply_filters(results)?;
if let Some(ref sort_options) = self.sort_options {
self.apply_sort(&mut results, sort_options);
}
if let Some(limit) = self.limit {
results.truncate(limit);
}
Ok(results)
}
pub fn indices(self) -> Result<Vec<usize>> {
Ok(self.execute()?.into_iter().map(|info| info.index).collect())
}
pub fn with_indices(self) -> Result<Vec<(usize, OwnedEvent)>> {
Ok(self
.execute()?
.into_iter()
.map(|info| (info.index, info.event))
.collect())
}
pub fn first(self) -> Result<Option<EventInfo>> {
let mut results = self.limit(1).execute()?;
Ok(results.pop())
}
pub fn count(self) -> Result<usize> {
Ok(self.execute()?.len())
}
pub fn timing(self) -> Result<EventTimer<'a>> {
let _indices: Vec<usize> = self.execute()?.into_iter().map(|info| info.index).collect();
Err(EditorError::command_failed(
"Cannot chain timing operations after query execution - use indices() first",
))
}
pub fn toggle_type(self) -> Result<EventToggler<'a>> {
let _indices: Vec<usize> = self.execute()?.into_iter().map(|info| info.index).collect();
Err(EditorError::command_failed(
"Cannot chain toggle operations after query execution - use indices() first",
))
}
pub fn effects(self) -> Result<EventEffector<'a>> {
let _indices: Vec<usize> = self.execute()?.into_iter().map(|info| info.index).collect();
Err(EditorError::command_failed(
"Cannot chain effect operations after query execution - use indices() first",
))
}
fn collect_events(&self) -> Result<Vec<EventInfo>> {
self.document
.parse_script_with(|script| -> Result<Vec<EventInfo>> {
let mut events = Vec::new();
let mut event_index = 0;
for section in script.sections() {
if let Section::Events(section_events) = section {
for event in section_events {
let event_info = EventInfo {
index: event_index,
event: OwnedEvent::from(event),
line_number: self.find_line_number(event)?,
range: self.find_event_range(event)?,
};
events.push(event_info);
event_index += 1;
}
}
}
Ok(events)
})?
}
fn apply_filters(&self, events: Vec<EventInfo>) -> Result<Vec<EventInfo>> {
let mut filtered = Vec::new();
for event_info in events {
if self.matches_filter(&event_info)? {
filtered.push(event_info);
}
}
Ok(filtered)
}
fn apply_sort(&self, events: &mut [EventInfo], options: &EventSortOptions) {
events.sort_by(|a, b| {
let primary_cmp = self.compare_by_criteria(a, b, &options.criteria);
match primary_cmp {
Ordering::Equal => {
if let Some(secondary) = &options.secondary {
let secondary_cmp = self.compare_by_criteria(a, b, secondary);
if options.ascending {
secondary_cmp
} else {
secondary_cmp.reverse()
}
} else {
Ordering::Equal
}
}
other => {
if options.ascending {
other
} else {
other.reverse()
}
}
}
});
}
fn find_line_number(&self, _event: &Event) -> Result<usize> {
Ok(1)
}
fn find_event_range(&self, _event: &Event) -> Result<Range> {
Ok(Range::new(Position::new(0), Position::new(0)))
}
}