sakurs_core/api/
output.rs1use std::time::Duration;
4
5#[derive(Debug, Clone)]
7pub struct Output {
8 pub boundaries: Vec<Boundary>,
10 pub metadata: ProcessingMetadata,
12}
13
14#[derive(Debug, Clone)]
16pub struct Boundary {
17 pub offset: usize,
19 pub char_offset: usize,
21}
22
23#[derive(Debug, Clone)]
25pub struct ProcessingMetadata {
26 pub duration: Duration,
28 pub strategy_used: String,
30 pub chunks_processed: usize,
32 pub stats: ProcessingStats,
34}
35
36#[derive(Debug, Clone)]
38pub struct ProcessingStats {
39 pub bytes_processed: usize,
41 pub chars_processed: usize,
43 pub sentence_count: usize,
45 pub avg_sentence_length: f32,
47}
48
49impl Output {
50 pub(crate) fn from_delta_stack_result(
52 result: crate::application::DeltaStackResult,
53 text: &str,
54 duration: Duration,
55 ) -> Self {
56 let (char_boundaries, total_chars) = Self::calculate_char_offsets(text, &result.boundaries);
59
60 let boundaries = result
61 .boundaries
62 .into_iter()
63 .zip(char_boundaries)
64 .map(|(offset, char_offset)| Boundary {
65 offset,
66 char_offset,
67 })
68 .collect::<Vec<_>>();
69
70 let sentence_count = boundaries.len();
71 let avg_sentence_length = if sentence_count > 0 {
72 total_chars as f32 / sentence_count as f32
73 } else {
74 0.0
75 };
76
77 let strategy_used = if result.thread_count > 1 {
79 format!("parallel ({} threads)", result.thread_count)
80 } else {
81 "sequential".to_string()
82 };
83
84 Self {
85 boundaries,
86 metadata: ProcessingMetadata {
87 duration,
88 strategy_used,
89 chunks_processed: result.chunk_count,
90 stats: ProcessingStats {
91 bytes_processed: text.len(),
92 chars_processed: total_chars,
93 sentence_count,
94 avg_sentence_length,
95 },
96 },
97 }
98 }
99
100 fn calculate_char_offsets(text: &str, byte_offsets: &[usize]) -> (Vec<usize>, usize) {
109 let mut char_offsets = Vec::with_capacity(byte_offsets.len());
110 let mut chars = 0usize;
111 let mut prev = 0usize;
112 for &off in byte_offsets {
113 chars += text[prev..off].chars().count();
114 char_offsets.push(chars);
115 prev = off;
116 }
117 let total = chars + text[prev..].chars().count();
118 (char_offsets, total)
119 }
120}