@@ -210,58 +210,6 @@ mod tests {
210210 Ok ( _) => panic ! ( "Expected error for chunk_size 0" ) ,
211211 }
212212 }
213-
214- #[ test]
215- fn test_build_normal_chunks ( ) {
216- let text = "Hello world! This is a test." ;
217- let chunks = build_normal_chunks ( text, 10 ) ;
218- assert_eq ! ( chunks. len( ) , 3 ) ;
219- assert_eq ! ( chunks[ 0 ] . len( ) , 10 ) ;
220- assert_eq ! ( chunks[ 1 ] . len( ) , 10 ) ;
221- assert_eq ! ( chunks[ 2 ] . len( ) , 8 ) ;
222- }
223-
224- #[ test]
225- fn test_build_code_chunks ( ) {
226- let text = "fn main() {\n println!(\" Hello\" );\n }" ;
227- let chunks = build_code_chunks ( text, 30 ) ;
228- // With overhead of 8 chars for ```\n and \n```, each chunk can hold 22 chars
229- assert ! ( chunks. len( ) >= 2 ) ;
230- // Each chunk should be wrapped in backticks
231- for chunk in & chunks {
232- assert ! ( chunk. starts_with( "```\n " ) ) ;
233- assert ! ( chunk. ends_with( "\n ```" ) ) ;
234- // And total size should not exceed limit
235- assert ! ( chunk. chars( ) . count( ) <= 30 ) ;
236- }
237- }
238-
239- #[ test]
240- fn test_build_quote_chunks ( ) {
241- let text = "Line 1\n Line 2\n Line 3" ;
242- let chunks = build_quote_chunks ( text, 20 ) ;
243- // Each line formatted: "> Line X\n" is 9 chars
244- // So we can fit 2 lines (18 chars) in 20 char limit
245- assert ! ( chunks. len( ) >= 2 ) ;
246- // Each chunk should have > prefix on lines
247- for chunk in & chunks {
248- assert ! ( chunk. starts_with( "> " ) ) ;
249- // And total size should not exceed limit
250- assert ! ( chunk. chars( ) . count( ) <= 20 , "Chunk exceeded size: {} chars" , chunk. chars( ) . count( ) ) ;
251- }
252- }
253-
254- #[ test]
255- fn test_quote_chunks_respects_limit ( ) {
256- // Test with a more realistic Discord limit
257- let text = "This is line one\n This is line two\n This is line three\n This is line four" ;
258- let chunks = build_quote_chunks ( text, 50 ) ;
259-
260- for chunk in & chunks {
261- let char_count = chunk. chars ( ) . count ( ) ;
262- assert ! ( char_count <= 50 , "Chunk size {} exceeds limit 50: {}" , char_count, chunk) ;
263- }
264- }
265213}
266214
267215/// Creates a temporary file from a byte slice and returns the path to the file.
@@ -1107,111 +1055,6 @@ fn get_clipboard_string() -> Result<String, String> {
11071055 . map_err ( |e| format ! ( "Failed to read clipboard contents: {}" , e) )
11081056}
11091057
1110- /// Builds normal chunks (no formatting) that fit within chunk_size
1111- fn build_normal_chunks ( text : & str , chunk_size : usize ) -> Vec < String > {
1112- let chars: Vec < char > = text. chars ( ) . collect ( ) ;
1113- let mut chunks = Vec :: new ( ) ;
1114- let mut i = 0 ;
1115-
1116- while i < chars. len ( ) {
1117- let end = std:: cmp:: min ( i + chunk_size, chars. len ( ) ) ;
1118- let chunk: String = chars[ i..end] . iter ( ) . collect ( ) ;
1119- chunks. push ( chunk) ;
1120- i = end;
1121- }
1122-
1123- chunks
1124- }
1125-
1126- /// Builds quote-formatted chunks where each line has "> " prefix
1127- /// Ensures the FORMATTED chunk (with prefixes) fits within chunk_size
1128- fn build_quote_chunks ( text : & str , chunk_size : usize ) -> Vec < String > {
1129- let lines: Vec < & str > = text. lines ( ) . collect ( ) ;
1130- let mut chunks = Vec :: new ( ) ;
1131- let mut current_chunk_lines = Vec :: new ( ) ;
1132- let mut current_formatted_size = 0 ;
1133-
1134- for line in lines {
1135- // Calculate what this line will be after formatting: "> " + line + "\n"
1136- let formatted_line_size = 2 + line. chars ( ) . count ( ) + 1 ; // "> " + line + newline
1137-
1138- // Check if adding this line would exceed the limit
1139- if current_formatted_size + formatted_line_size > chunk_size && !current_chunk_lines. is_empty ( ) {
1140- // Finalize current chunk
1141- let chunk_text = current_chunk_lines
1142- . iter ( )
1143- . map ( |l| format ! ( "> {}" , l) )
1144- . collect :: < Vec < String > > ( )
1145- . join ( "\n " ) ;
1146- chunks. push ( chunk_text) ;
1147-
1148- // Start new chunk
1149- current_chunk_lines. clear ( ) ;
1150- current_formatted_size = 0 ;
1151- }
1152-
1153- // If a single line is too long for chunk_size, split it by characters
1154- if formatted_line_size > chunk_size {
1155- // Split this long line into character chunks
1156- let chars: Vec < char > = line. chars ( ) . collect ( ) ;
1157- let max_chars_per_chunk = chunk_size. saturating_sub ( 3 ) ; // Reserve space for "> " and potential newline
1158-
1159- let mut i = 0 ;
1160- while i < chars. len ( ) {
1161- let end = std:: cmp:: min ( i + max_chars_per_chunk, chars. len ( ) ) ;
1162- let line_chunk: String = chars[ i..end] . iter ( ) . collect ( ) ;
1163- let formatted = format ! ( "> {}" , line_chunk) ;
1164- chunks. push ( formatted) ;
1165- i = end;
1166- }
1167- } else {
1168- // Add line to current chunk
1169- current_chunk_lines. push ( line) ;
1170- current_formatted_size += formatted_line_size;
1171- }
1172- }
1173-
1174- // Don't forget the last chunk
1175- if !current_chunk_lines. is_empty ( ) {
1176- let chunk_text = current_chunk_lines
1177- . iter ( )
1178- . map ( |l| format ! ( "> {}" , l) )
1179- . collect :: < Vec < String > > ( )
1180- . join ( "\n " ) ;
1181- chunks. push ( chunk_text) ;
1182- }
1183-
1184- chunks
1185- }
1186-
1187- /// Builds code block chunks wrapped in triple backticks
1188- /// Ensures the FORMATTED chunk (with ```) fits within chunk_size
1189- fn build_code_chunks ( text : & str , chunk_size : usize ) -> Vec < String > {
1190- // Code block format: ```\n{content}\n```
1191- // That's 4 chars for "```\n" at start and 4 chars for "\n```" at end = 8 chars overhead
1192- let overhead = 8 ;
1193-
1194- if chunk_size <= overhead {
1195- // Not enough space for formatting, return empty
1196- return vec ! [ ] ;
1197- }
1198-
1199- let available_size = chunk_size - overhead;
1200- let chars: Vec < char > = text. chars ( ) . collect ( ) ;
1201- let mut chunks = Vec :: new ( ) ;
1202- let mut i = 0 ;
1203-
1204- while i < chars. len ( ) {
1205- let end = std:: cmp:: min ( i + available_size, chars. len ( ) ) ;
1206- let chunk: String = chars[ i..end] . iter ( ) . collect ( ) ;
1207- let formatted = format ! ( "```\n {}\n ```" , chunk) ;
1208- chunks. push ( formatted) ;
1209- i = end;
1210- }
1211-
1212- chunks
1213- }
1214-
12151058fn paste_clipboard_in_chunks ( chunk_size : usize , format : & str ) -> Result < String , String > {
12161059 if chunk_size == 0 {
12171060 return Err ( "Chunk size must be greater than 0" . to_string ( ) ) ;
@@ -1229,18 +1072,101 @@ fn paste_clipboard_in_chunks(chunk_size: usize, format: &str) -> Result<String,
12291072
12301073 let mut enigo = Enigo :: new ( ) ;
12311074
1232- // Build chunks based on format type, ensuring formatted size fits within chunk_size
1075+ // Create chunks based on format type
12331076 let chunks: Vec < String > = match format {
1234- "quote" => build_quote_chunks ( & clipboard_text, chunk_size) ,
1235- "code" | "codeblock" => build_code_chunks ( & clipboard_text, chunk_size) ,
1236- _ => build_normal_chunks ( & clipboard_text, chunk_size) , // "normal" or default
1077+ "quote" => {
1078+ // For quotes, we need to respect line boundaries and account for "> " prefix
1079+ let lines: Vec < & str > = clipboard_text. lines ( ) . collect ( ) ;
1080+ let mut chunks_vec = Vec :: new ( ) ;
1081+ let mut current_chunk_lines = Vec :: new ( ) ;
1082+ let mut current_size = 0 ;
1083+
1084+ for line in lines {
1085+ // Calculate size with "> " prefix and newline
1086+ let formatted_line_size = line. chars ( ) . count ( ) + 2 ; // +2 for "> "
1087+ let size_with_newline = if current_chunk_lines. is_empty ( ) {
1088+ formatted_line_size
1089+ } else {
1090+ formatted_line_size + 1 // +1 for newline
1091+ } ;
1092+
1093+ // If adding this line would exceed chunk_size, start a new chunk
1094+ if current_size + size_with_newline > chunk_size && !current_chunk_lines. is_empty ( ) {
1095+ // Format and save current chunk
1096+ let formatted_chunk = current_chunk_lines
1097+ . iter ( )
1098+ . map ( |l| format ! ( "> {}" , l) )
1099+ . collect :: < Vec < String > > ( )
1100+ . join ( "\n " ) ;
1101+ chunks_vec. push ( formatted_chunk) ;
1102+
1103+ // Start new chunk with current line
1104+ current_chunk_lines = vec ! [ line] ;
1105+ current_size = formatted_line_size;
1106+ } else {
1107+ // Add line to current chunk
1108+ current_chunk_lines. push ( line) ;
1109+ current_size += size_with_newline;
1110+ }
1111+ }
1112+
1113+ // Don't forget the last chunk
1114+ if !current_chunk_lines. is_empty ( ) {
1115+ let formatted_chunk = current_chunk_lines
1116+ . iter ( )
1117+ . map ( |l| format ! ( "> {}" , l) )
1118+ . collect :: < Vec < String > > ( )
1119+ . join ( "\n " ) ;
1120+ chunks_vec. push ( formatted_chunk) ;
1121+ }
1122+
1123+ chunks_vec
1124+ }
1125+ "code" | "codeblock" => {
1126+ // For code blocks, account for triple backticks (8 chars: ```\n and \n```)
1127+ let overhead = 8 ;
1128+ let available_size = if chunk_size > overhead {
1129+ chunk_size - overhead
1130+ } else {
1131+ return Err ( "Chunk size too small for code block formatting (needs at least 9 characters)" . to_string ( ) ) ;
1132+ } ;
1133+
1134+ let chars: Vec < char > = clipboard_text. chars ( ) . collect ( ) ;
1135+ let mut chunks_vec = Vec :: new ( ) ;
1136+ let mut i = 0 ;
1137+
1138+ while i < chars. len ( ) {
1139+ let end = std:: cmp:: min ( i + available_size, chars. len ( ) ) ;
1140+ let chunk_text: String = chars[ i..end] . iter ( ) . collect ( ) ;
1141+ let formatted_chunk = format ! ( "```\n {}\n ```" , chunk_text) ;
1142+ chunks_vec. push ( formatted_chunk) ;
1143+ i = end;
1144+ }
1145+
1146+ chunks_vec
1147+ }
1148+ _ => {
1149+ // "normal" - simple character-based splitting
1150+ let chars: Vec < char > = clipboard_text. chars ( ) . collect ( ) ;
1151+ let mut chunks_vec = Vec :: new ( ) ;
1152+ let mut i = 0 ;
1153+
1154+ while i < chars. len ( ) {
1155+ let end = std:: cmp:: min ( i + chunk_size, chars. len ( ) ) ;
1156+ let chunk: String = chars[ i..end] . iter ( ) . collect ( ) ;
1157+ chunks_vec. push ( chunk) ;
1158+ i = end;
1159+ }
1160+
1161+ chunks_vec
1162+ }
12371163 } ;
12381164
1239- let total_chars = clipboard_text. len ( ) ;
1165+ let total_chars = clipboard_text. chars ( ) . count ( ) ;
12401166 let chunks_pasted = chunks. len ( ) ;
12411167
12421168 // Paste each chunk
1243- for formatted_chunk in chunks {
1169+ for formatted_chunk in & chunks {
12441170 // Set the clipboard to this formatted chunk
12451171 clipboard
12461172 . set_contents ( formatted_chunk. clone ( ) )
0 commit comments