1pub mod config;
8pub mod types;
9
10#[cfg(test)]
11mod tests;
12
13pub use config::*;
15pub use types::*;
16
17use crate::builder::Circuit;
18use crate::scirs2_integration::SciRS2CircuitAnalyzer;
19use quantrs2_core::error::QuantRS2Result;
20use std::collections::HashMap;
21use std::sync::{Arc, RwLock};
22use std::time::Instant;
23
24pub struct QuantumFormatter<const N: usize> {
26 circuit: Circuit<N>,
28 pub config: FormatterConfig,
30 analyzer: SciRS2CircuitAnalyzer,
32 layout_optimizer: Arc<RwLock<LayoutOptimizer<N>>>,
34 style_enforcer: Arc<RwLock<StyleEnforcer<N>>>,
36 code_organizer: Arc<RwLock<CodeOrganizer<N>>>,
38 comment_formatter: Arc<RwLock<CommentFormatter<N>>>,
40 whitespace_manager: Arc<RwLock<WhitespaceManager<N>>>,
42 alignment_engine: Arc<RwLock<AlignmentEngine<N>>>,
44}
45
46impl<const N: usize> QuantumFormatter<N> {
47 #[must_use]
49 pub fn new(circuit: Circuit<N>) -> Self {
50 Self {
51 circuit,
52 config: FormatterConfig::default(),
53 analyzer: SciRS2CircuitAnalyzer::new(),
54 layout_optimizer: Arc::new(RwLock::new(LayoutOptimizer::new())),
55 style_enforcer: Arc::new(RwLock::new(StyleEnforcer::new())),
56 code_organizer: Arc::new(RwLock::new(CodeOrganizer::new())),
57 comment_formatter: Arc::new(RwLock::new(CommentFormatter::new())),
58 whitespace_manager: Arc::new(RwLock::new(WhitespaceManager::new())),
59 alignment_engine: Arc::new(RwLock::new(AlignmentEngine::new())),
60 }
61 }
62
63 pub fn format_circuit(&mut self) -> QuantRS2Result<FormattingResult> {
65 let start_time = Instant::now();
66 let mut changes = Vec::new();
67
68 let code_structure = self.analyze_code_structure()?;
70
71 let layout_changes = self.optimize_layout(&code_structure)?;
73 changes.extend(layout_changes);
74
75 let style_changes = self.enforce_style(&code_structure)?;
77 changes.extend(style_changes);
78
79 let org_changes = self.organize_code(&code_structure)?;
81 changes.extend(org_changes);
82
83 let comment_changes = self.format_comments(&code_structure)?;
85 changes.extend(comment_changes);
86
87 let ws_changes = self.manage_whitespace(&code_structure)?;
89 changes.extend(ws_changes);
90
91 let align_changes = self.apply_alignment(&code_structure)?;
93 changes.extend(align_changes);
94
95 let formatted_code = self.build_formatted_code(&code_structure, &changes)?;
97
98 let statistics = FormattingStatistics {
100 total_lines: formatted_code.line_count,
101 lines_modified: changes.len(),
102 characters_added: 0,
103 characters_removed: 0,
104 formatting_time: start_time.elapsed(),
105 };
106
107 let style_info = self.collect_style_information(&changes)?;
109
110 let quality = self.calculate_quality_metrics(&formatted_code)?;
112
113 Ok(FormattingResult {
114 formatted_circuit: formatted_code,
115 statistics,
116 changes,
117 style_information: style_info,
118 quality_metrics: quality,
119 duration: start_time.elapsed(),
120 })
121 }
122
123 pub fn assess_style_compliance(
125 &self,
126 style_info: &StyleInformation,
127 ) -> QuantRS2Result<StyleCompliance> {
128 let level = if style_info.compliance_score >= 0.9 {
129 ComplianceLevel::Excellent
130 } else if style_info.compliance_score >= 0.7 {
131 ComplianceLevel::Good
132 } else if style_info.compliance_score >= 0.5 {
133 ComplianceLevel::Fair
134 } else {
135 ComplianceLevel::Poor
136 };
137
138 Ok(StyleCompliance {
139 compliance_level: level,
140 issues: Vec::new(),
141 score: style_info.compliance_score,
142 })
143 }
144
145 fn analyze_code_structure(&self) -> QuantRS2Result<CodeStructure> {
146 Ok(CodeStructure::default())
147 }
148
149 fn optimize_layout(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
150 let optimizer = self.layout_optimizer.read().map_err(|_| {
151 quantrs2_core::error::QuantRS2Error::InvalidOperation(
152 "Failed to acquire layout optimizer lock".to_string(),
153 )
154 })?;
155 optimizer.optimize_layout(code, &self.config)
156 }
157
158 fn enforce_style(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
159 let enforcer = self.style_enforcer.read().map_err(|_| {
160 quantrs2_core::error::QuantRS2Error::InvalidOperation(
161 "Failed to acquire style enforcer lock".to_string(),
162 )
163 })?;
164 enforcer.enforce_style(code, &self.config)
165 }
166
167 fn organize_code(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
168 let organizer = self.code_organizer.read().map_err(|_| {
169 quantrs2_core::error::QuantRS2Error::InvalidOperation(
170 "Failed to acquire code organizer lock".to_string(),
171 )
172 })?;
173 organizer.organize_code(code, &self.config)
174 }
175
176 fn format_comments(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
177 let formatter = self.comment_formatter.read().map_err(|_| {
178 quantrs2_core::error::QuantRS2Error::InvalidOperation(
179 "Failed to acquire comment formatter lock".to_string(),
180 )
181 })?;
182 formatter.format_comments(code, &self.config)
183 }
184
185 fn manage_whitespace(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
186 let manager = self.whitespace_manager.read().map_err(|_| {
187 quantrs2_core::error::QuantRS2Error::InvalidOperation(
188 "Failed to acquire whitespace manager lock".to_string(),
189 )
190 })?;
191 manager.manage_whitespace(code, &self.config)
192 }
193
194 fn apply_alignment(&self, code: &CodeStructure) -> QuantRS2Result<Vec<FormattingChange>> {
195 let engine = self.alignment_engine.read().map_err(|_| {
196 quantrs2_core::error::QuantRS2Error::InvalidOperation(
197 "Failed to acquire alignment engine lock".to_string(),
198 )
199 })?;
200 engine.apply_alignment(code, &self.config)
201 }
202
203 fn build_formatted_code(
204 &self,
205 code: &CodeStructure,
206 _changes: &[FormattingChange],
207 ) -> QuantRS2Result<FormattedCircuit> {
208 let code = format!("// Formatted circuit with {N} qubits\n");
209 let line_count = code.lines().count();
210 let char_count = code.chars().count();
211
212 Ok(FormattedCircuit {
213 code,
214 line_count,
215 char_count,
216 })
217 }
218
219 const fn collect_style_information(
220 &self,
221 _changes: &[FormattingChange],
222 ) -> QuantRS2Result<StyleInformation> {
223 Ok(StyleInformation {
224 applied_rules: Vec::new(),
225 violations_fixed: Vec::new(),
226 compliance_score: 0.95,
227 consistency_metrics: ConsistencyMetrics {
228 naming_consistency: 0.95,
229 indentation_consistency: 0.95,
230 spacing_consistency: 0.95,
231 comment_consistency: 0.95,
232 overall_consistency: 0.95,
233 },
234 })
235 }
236
237 const fn calculate_quality_metrics(
238 &self,
239 code: &FormattedCircuit,
240 ) -> QuantRS2Result<QualityMetrics> {
241 Ok(QualityMetrics {
242 readability_score: 0.9,
243 maintainability_score: 0.9,
244 complexity_score: 0.8,
245 overall_quality: 0.87,
246 })
247 }
248}
249
250pub struct LayoutOptimizer<const N: usize> {
252 }
254
255impl<const N: usize> LayoutOptimizer<N> {
256 #[must_use]
257 pub const fn new() -> Self {
258 Self {}
259 }
260
261 pub fn optimize_layout(
262 &self,
263 code: &CodeStructure,
264 config: &FormatterConfig,
265 ) -> QuantRS2Result<Vec<FormattingChange>> {
266 let max_len = config.max_line_length;
271 let mut changes = Vec::new();
272 for section in &code.sections {
273 if section.content.chars().count() > max_len {
274 changes.push(FormattingChange {
275 change_type: ChangeType::LineBreak,
276 start: Position {
277 line: section.start_line,
278 column: 0,
279 },
280 end: Position {
281 line: section.end_line,
282 column: max_len,
283 },
284 old_text: section.content.clone(),
285 new_text: format!("// section '{}' exceeds {} cols\n", section.name, max_len),
286 });
287 }
288 }
289 Ok(changes)
290 }
291}
292
293impl<const N: usize> Default for LayoutOptimizer<N> {
294 fn default() -> Self {
295 Self::new()
296 }
297}
298
299pub struct StyleEnforcer<const N: usize> {
301 }
303
304impl<const N: usize> StyleEnforcer<N> {
305 #[must_use]
306 pub const fn new() -> Self {
307 Self {}
308 }
309
310 pub fn enforce_style(
311 &self,
312 code: &CodeStructure,
313 config: &FormatterConfig,
314 ) -> QuantRS2Result<Vec<FormattingChange>> {
315 let mut changes = Vec::new();
320 if !config.spacing.after_commas {
321 return Ok(changes);
322 }
323 for section in &code.sections {
324 if section.content.contains(",") && !section.content.contains(", ") {
325 changes.push(FormattingChange {
326 change_type: ChangeType::Spacing,
327 start: Position {
328 line: section.start_line,
329 column: 0,
330 },
331 end: Position {
332 line: section.end_line,
333 column: 0,
334 },
335 old_text: section.content.clone(),
336 new_text: section.content.replace(",", ", "),
337 });
338 }
339 }
340 Ok(changes)
341 }
342}
343
344impl<const N: usize> Default for StyleEnforcer<N> {
345 fn default() -> Self {
346 Self::new()
347 }
348}
349
350pub struct CodeOrganizer<const N: usize> {
352 }
354
355impl<const N: usize> CodeOrganizer<N> {
356 #[must_use]
357 pub const fn new() -> Self {
358 Self {}
359 }
360
361 pub fn organize_code(
362 &self,
363 code: &CodeStructure,
364 config: &FormatterConfig,
365 ) -> QuantRS2Result<Vec<FormattingChange>> {
366 let order = &config.organization.section_ordering;
371 if order.is_empty() {
372 return Ok(Vec::new());
373 }
374 let rank = |name: &str| -> Option<usize> {
375 order.iter().position(|n| n.eq_ignore_ascii_case(name))
376 };
377 let mut changes = Vec::new();
378 let mut last_rank: Option<usize> = None;
379 for section in &code.sections {
380 let r = rank(§ion.name);
381 if let (Some(prev), Some(cur)) = (last_rank, r) {
382 if cur < prev {
383 changes.push(FormattingChange {
384 change_type: ChangeType::Organization,
385 start: Position {
386 line: section.start_line,
387 column: 0,
388 },
389 end: Position {
390 line: section.end_line,
391 column: 0,
392 },
393 old_text: section.name.clone(),
394 new_text: format!(
395 "move '{}' to position {} per section_ordering",
396 section.name, cur
397 ),
398 });
399 }
400 }
401 if r.is_some() {
402 last_rank = r;
403 }
404 }
405 Ok(changes)
406 }
407}
408
409impl<const N: usize> Default for CodeOrganizer<N> {
410 fn default() -> Self {
411 Self::new()
412 }
413}
414
415pub struct CommentFormatter<const N: usize> {
417 state: CommentFormatterState,
418}
419
420impl<const N: usize> CommentFormatter<N> {
421 #[must_use]
422 pub fn new() -> Self {
423 Self {
424 state: CommentFormatterState {
425 rules: Vec::new(),
426 templates: HashMap::new(),
427 quality_threshold: 0.8,
428 },
429 }
430 }
431
432 pub fn format_comments(
433 &self,
434 code: &CodeStructure,
435 config: &FormatterConfig,
436 ) -> QuantRS2Result<Vec<FormattingChange>> {
437 let target = config.comments.target_comment_density;
441 let mut changes = Vec::new();
442 for section in &code.sections {
443 let total_lines = section.content.lines().count().max(1);
444 let comment_lines = section
445 .content
446 .lines()
447 .filter(|line| {
448 let trimmed = line.trim_start();
449 trimmed.starts_with("//") || trimmed.starts_with('#')
450 })
451 .count();
452 let density = comment_lines as f64 / total_lines as f64;
453 if density + f64::EPSILON < target {
454 changes.push(FormattingChange {
455 change_type: ChangeType::Comment,
456 start: Position {
457 line: section.start_line,
458 column: 0,
459 },
460 end: Position {
461 line: section.end_line,
462 column: 0,
463 },
464 old_text: section.content.clone(),
465 new_text: format!(
466 "// section '{}' has {:.2} comment density (< {:.2})\n",
467 section.name, density, target
468 ),
469 });
470 }
471 }
472 Ok(changes)
473 }
474}
475
476impl<const N: usize> Default for CommentFormatter<N> {
477 fn default() -> Self {
478 Self::new()
479 }
480}
481
482pub struct WhitespaceManager<const N: usize> {
484 rules: Vec<WhitespaceRule>,
485 current_state: WhitespaceState,
486 optimization: WhitespaceOptimization,
487}
488
489#[derive(Debug, Clone)]
490struct WhitespaceRule {
491 name: String,
492 pattern: String,
493}
494
495impl<const N: usize> WhitespaceManager<N> {
496 #[must_use]
497 pub const fn new() -> Self {
498 Self {
499 rules: Vec::new(),
500 current_state: WhitespaceState {
501 indentation_level: 0,
502 line_length: 0,
503 pending_changes: Vec::new(),
504 statistics: WhitespaceStatistics {
505 total_whitespace: 0,
506 indentation_chars: 0,
507 spacing_chars: 0,
508 line_breaks: 0,
509 consistency_score: 1.0,
510 },
511 },
512 optimization: WhitespaceOptimization {
513 remove_trailing: true,
514 normalize_indentation: true,
515 optimize_line_breaks: true,
516 compress_empty_lines: true,
517 target_compression: 0.1,
518 },
519 }
520 }
521
522 pub fn manage_whitespace(
523 &self,
524 code: &CodeStructure,
525 _config: &FormatterConfig,
526 ) -> QuantRS2Result<Vec<FormattingChange>> {
527 let mut changes = Vec::new();
532 if !self.optimization.remove_trailing {
533 return Ok(changes);
534 }
535 for section in &code.sections {
536 for (offset, line) in section.content.lines().enumerate() {
537 let stripped = line.trim_end();
538 if stripped.len() != line.len() {
539 let line_no = section.start_line + offset;
540 changes.push(FormattingChange {
541 change_type: ChangeType::Spacing,
542 start: Position {
543 line: line_no,
544 column: stripped.len(),
545 },
546 end: Position {
547 line: line_no,
548 column: line.len(),
549 },
550 old_text: line.to_string(),
551 new_text: stripped.to_string(),
552 });
553 }
554 }
555 }
556 Ok(changes)
557 }
558}
559
560impl<const N: usize> Default for WhitespaceManager<N> {
561 fn default() -> Self {
562 Self::new()
563 }
564}
565
566pub struct AlignmentEngine<const N: usize> {
568 rules: Vec<AlignmentRule>,
569 current_state: AlignmentState,
570 optimization: AlignmentOptimization,
571}
572
573#[derive(Debug, Clone)]
574struct AlignmentRule {
575 name: String,
576 column: usize,
577}
578
579impl<const N: usize> AlignmentEngine<N> {
580 #[must_use]
581 pub const fn new() -> Self {
582 Self {
583 rules: Vec::new(),
584 current_state: AlignmentState {
585 active_alignments: Vec::new(),
586 alignment_columns: Vec::new(),
587 statistics: AlignmentStatistics {
588 total_alignments: 0,
589 successful_alignments: 0,
590 average_quality: 0.0,
591 consistency_score: 1.0,
592 },
593 },
594 optimization: AlignmentOptimization {
595 auto_detect: true,
596 quality_threshold: 0.8,
597 max_distance: 10,
598 prefer_compact: true,
599 },
600 }
601 }
602
603 pub fn apply_alignment(
604 &self,
605 code: &CodeStructure,
606 config: &FormatterConfig,
607 ) -> QuantRS2Result<Vec<FormattingChange>> {
608 let threshold = config.alignment.column_alignment_threshold.max(1);
613 let mut changes = Vec::new();
614 for section in &code.sections {
615 let mut indents: Vec<usize> = section
616 .content
617 .lines()
618 .filter(|line| !line.trim().is_empty())
619 .map(|line| line.len() - line.trim_start().len())
620 .collect();
621 if indents.len() < threshold {
622 continue;
623 }
624 indents.sort_unstable();
625 let min = indents.first().copied().unwrap_or(0);
626 let max = indents.last().copied().unwrap_or(0);
627 if max > min {
628 changes.push(FormattingChange {
629 change_type: ChangeType::Alignment,
630 start: Position {
631 line: section.start_line,
632 column: min,
633 },
634 end: Position {
635 line: section.end_line,
636 column: max,
637 },
638 old_text: section.content.clone(),
639 new_text: format!("// align to column {min} for section '{}'\n", section.name),
640 });
641 }
642 }
643 Ok(changes)
644 }
645}
646
647impl<const N: usize> Default for AlignmentEngine<N> {
648 fn default() -> Self {
649 Self::new()
650 }
651}