aboutsummaryrefslogtreecommitdiff
path: root/libpsi-visualizer/src
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-24 14:48:36 +0200
committerhachem <im@hachem.wtf>2026-08-24 14:48:36 +0200
commit24d639224ca11112025289065d7538851606b56e (patch)
treee7e26c89cd20099f03ff32727ba0af2cf4762088 /libpsi-visualizer/src
parent548dc42d9f454cb8c29fddb88ca41f8b1b595882 (diff)
[chore]: unwrap project
Diffstat (limited to 'libpsi-visualizer/src')
-rw-r--r--libpsi-visualizer/src/cli/horizontal_cli.rs463
-rw-r--r--libpsi-visualizer/src/cli/mod.rs7
-rw-r--r--libpsi-visualizer/src/cli/vertical_cli.rs367
-rw-r--r--libpsi-visualizer/src/cli/visualizer.rs3
-rw-r--r--libpsi-visualizer/src/lib.rs2
5 files changed, 0 insertions, 842 deletions
diff --git a/libpsi-visualizer/src/cli/horizontal_cli.rs b/libpsi-visualizer/src/cli/horizontal_cli.rs
deleted file mode 100644
index f1a6ba4..0000000
--- a/libpsi-visualizer/src/cli/horizontal_cli.rs
+++ /dev/null
@@ -1,463 +0,0 @@
-use super::visualizer::Visualizer;
-use core::fmt;
-use libpsi_core::{GateOp, QuantumCircuit};
-
-pub struct HorizontalRenderer<'a> {
- circuit: &'a QuantumCircuit,
-}
-
-impl<'a> HorizontalRenderer<'a> {
- pub fn new(circuit: &'a QuantumCircuit) -> Self {
- HorizontalRenderer { circuit }
- }
-}
-
-impl<'a> Visualizer for HorizontalRenderer<'a> {
- fn export(&self) -> String {
- format!("{}", self)
- }
-}
-
-impl<'a> fmt::Display for HorizontalRenderer<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let nq = self.circuit.num_qubits();
- let nc = self.circuit.num_classical();
- let ops = self.circuit.operations();
-
- let mut q_lines: Vec<String> = (0..nq).map(|i| format!("q{}: ", i)).collect();
- let mut c_lines: Vec<String> = (0..nc).map(|i| format!("c{}: ", i)).collect();
-
- let max_label = q_lines
- .iter()
- .chain(c_lines.iter())
- .map(|s| s.len())
- .max()
- .unwrap_or(3);
-
- for line in &mut q_lines {
- while line.len() < max_label {
- line.insert(0, ' ');
- }
- }
- for line in &mut c_lines {
- while line.len() < max_label {
- line.insert(0, ' ');
- }
- }
- let mut gap_line = " ".repeat(max_label);
-
- if ops.is_empty() {
- for line in &q_lines {
- writeln!(f, "{}───░", line)?;
- }
- if nc > 0 {
- writeln!(f, "{} ░", gap_line)?;
- for line in &c_lines {
- writeln!(f, "{}═══░", line)?;
- }
- }
- return Ok(());
- }
-
- for op in ops {
- let q_targets = op.quantum_targets();
-
- let min_q = q_targets.iter().min().copied().unwrap_or(0);
- let max_q = q_targets.iter().max().copied().unwrap_or(0);
-
- match op {
- GateOp::H(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[H]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::X(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[X]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Y(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[Y]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Z(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[Z]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::S(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[S]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::T(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[T]─");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Sdg(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[S†]─");
- } else {
- line.push_str("──────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("══════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Tdg(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[T†]─");
- } else {
- line.push_str("──────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("══════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Sx(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[√X]─");
- } else {
- line.push_str("──────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("══════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Sxdg(t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str("─[√X†]─");
- } else {
- line.push_str("───────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═══════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Rx(t, theta) => {
- let label = format!("[Rx({:.2})]", theta);
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::Ry(t, theta) => {
- let label = format!("[Ry({:.2})]", theta);
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::Rz(t, theta) => {
- let label = format!("[Rz({:.2})]", theta);
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::P(t, theta) => {
- let label = format!("[P({:.2})]", theta);
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::U1(t, lambda) => {
- let label = format!("[U1({:.2})]", lambda);
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::U2(t, _, _) => {
- let label = "[U2]";
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::U3(t, _, _, _) => {
- let label = "[U3]";
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *t {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::CRx(c, t, theta) | GateOp::CRy(c, t, theta) | GateOp::CRz(c, t, theta) | GateOp::CP(c, t, theta) => {
- let label = match op {
- GateOp::CRx(_, _, _) => format!("[CRx({:.2})]", theta),
- GateOp::CRy(_, _, _) => format!("[CRy({:.2})]", theta),
- GateOp::CRz(_, _, _) => format!("[CRz({:.2})]", theta),
- GateOp::CP(_, _, _) => format!("[CP({:.2})]", theta),
- _ => unreachable!(),
- };
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *c {
- line.push_str(&format!("─{}─", "●".to_string() + &"─".repeat(label.len() - 1)));
- } else if i == *t {
- line.push_str(&format!("─{}─", label));
- } else if i > min_q && i < max_q {
- line.push_str(&format!("─{}─", "│".to_string() + &"─".repeat(label.len() - 1)));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- GateOp::CNOT(c, t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *c {
- line.push_str("──●──");
- } else if i == *t {
- line.push_str("──⊕──");
- } else if i > min_q && i < max_q {
- line.push_str("──│──");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::CZ(c, t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *c || i == *t {
- line.push_str("──●──");
- } else if i > min_q && i < max_q {
- line.push_str("──│──");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::SWAP(a, b) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *a || i == *b {
- line.push_str("──╳──");
- } else if i > min_q && i < max_q {
- line.push_str("──│──");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::CCNOT(c1, c2, t) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *c1 || i == *c2 {
- line.push_str("──●──");
- } else if i == *t {
- line.push_str("──⊕──");
- } else if i > min_q && i < max_q {
- line.push_str("──│──");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::CSWAP(c, t1, t2) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *c {
- line.push_str("──●──");
- } else if i == *t1 || i == *t2 {
- line.push_str("──╳──");
- } else if i > min_q && i < max_q {
- line.push_str("──│──");
- } else {
- line.push_str("─────");
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str("═════");
- }
- gap_line.push_str(" ");
- }
- GateOp::Measure(q, c) => {
- for (i, line) in q_lines.iter_mut().enumerate() {
- if i == *q {
- line.push_str("─[M]─");
- } else if i > *q {
- line.push_str("──║──");
- } else {
- line.push_str("─────");
- }
- }
- for (i, line) in c_lines.iter_mut().enumerate() {
- if i == *c {
- line.push_str("══╩══");
- } else if i < *c {
- line.push_str("══║══");
- } else {
- line.push_str("═════");
- }
- }
- gap_line.push_str(" ║ ");
- }
- GateOp::Custom(gate, targets) => {
- let name = &gate.name;
- let label = format!("[{}]", name);
-
- for (i, line) in q_lines.iter_mut().enumerate() {
- if targets.contains(&i) {
- if i == targets[0] {
- line.push_str(&format!("─{}─", label));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- } else if i > min_q && i < max_q {
- line.push_str(&format!(
- "─{}─",
- "│".to_string() + &"─".repeat(label.len() - 1)
- ));
- } else {
- line.push_str(&format!("─{}─", "─".repeat(label.len())));
- }
- }
- for line in c_lines.iter_mut() {
- line.push_str(&format!("═{}═", "═".repeat(label.len())));
- }
- gap_line.push_str(&format!(" {} ", " ".repeat(label.len())));
- }
- }
- }
-
- for line in &q_lines {
- writeln!(f, "{}░", line)?;
- }
- if nc > 0 {
- writeln!(f, "{}░", gap_line)?;
- for line in &c_lines {
- writeln!(f, "{}░", line)?;
- }
- }
-
- Ok(())
- }
-}
diff --git a/libpsi-visualizer/src/cli/mod.rs b/libpsi-visualizer/src/cli/mod.rs
deleted file mode 100644
index 213311b..0000000
--- a/libpsi-visualizer/src/cli/mod.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-pub mod horizontal_cli;
-pub mod vertical_cli;
-pub mod visualizer;
-
-pub use horizontal_cli::*;
-pub use vertical_cli::*;
-pub use visualizer::*;
diff --git a/libpsi-visualizer/src/cli/vertical_cli.rs b/libpsi-visualizer/src/cli/vertical_cli.rs
deleted file mode 100644
index 6698961..0000000
--- a/libpsi-visualizer/src/cli/vertical_cli.rs
+++ /dev/null
@@ -1,367 +0,0 @@
-use super::visualizer::Visualizer;
-use core::fmt;
-use libpsi_core::{GateOp, QuantumCircuit};
-
-pub struct VerticalRenderer<'a> {
- circuit: &'a QuantumCircuit,
-}
-
-impl<'a> VerticalRenderer<'a> {
- pub fn new(circuit: &'a QuantumCircuit) -> Self {
- VerticalRenderer { circuit }
- }
-
- fn gate_label(op: &GateOp) -> String {
- match op {
- GateOp::H(_) => "[H]".to_string(),
- GateOp::X(_) => "[X]".to_string(),
- GateOp::Y(_) => "[Y]".to_string(),
- GateOp::Z(_) => "[Z]".to_string(),
- GateOp::S(_) => "[S]".to_string(),
- GateOp::T(_) => "[T]".to_string(),
- GateOp::Sdg(_) => "[S†]".to_string(),
- GateOp::Tdg(_) => "[T†]".to_string(),
- GateOp::Sx(_) => "[√X]".to_string(),
- GateOp::Sxdg(_) => "[√X†]".to_string(),
- GateOp::Rx(_, theta) => format!("[Rx({:.2})]", theta),
- GateOp::Ry(_, theta) => format!("[Ry({:.2})]", theta),
- GateOp::Rz(_, theta) => format!("[Rz({:.2})]", theta),
- GateOp::P(_, theta) => format!("[P({:.2})]", theta),
- GateOp::U1(_, lambda) => format!("[U1({:.2})]", lambda),
- GateOp::U2(_, _, _) => "[U2]".to_string(),
- GateOp::U3(_, _, _, _) => "[U3]".to_string(),
- GateOp::CRx(_, _, _) => "[CRx]".to_string(),
- GateOp::CRy(_, _, _) => "[CRy]".to_string(),
- GateOp::CRz(_, _, _) => "[CRz]".to_string(),
- GateOp::CP(_, _, _) => "[CP]".to_string(),
- GateOp::CNOT(_, _) => "●".to_string(),
- GateOp::CZ(_, _) => "●".to_string(),
- GateOp::SWAP(_, _) => "╳".to_string(),
- GateOp::CCNOT(_, _, _) => "●".to_string(),
- GateOp::CSWAP(_, _, _) => "●".to_string(),
- GateOp::Measure(_, _) => "[M]".to_string(),
- GateOp::Custom(gate, _) => format!("[{}]", gate.name),
- }
- }
-
- fn calculate_col_width(&self) -> usize {
- let min_width = 3;
- let mut max_label_len = min_width;
-
- for op in self.circuit.operations() {
- let label = Self::gate_label(op);
- let char_count: usize = label.chars().count();
- if char_count > max_label_len {
- max_label_len = char_count;
- }
- }
-
- let width = max_label_len + 2;
- if width % 2 == 0 {
- width + 1
- } else {
- width
- }
- }
-}
-
-impl<'a> Visualizer for VerticalRenderer<'a> {
- fn export(&self) -> String {
- format!("{}", self)
- }
-}
-
-impl<'a> fmt::Display for VerticalRenderer<'a> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- let nq = self.circuit.num_qubits();
- let nc = self.circuit.num_classical();
- let ops = self.circuit.operations();
-
- let col_width = self.calculate_col_width();
- let gap_width = 3;
-
- let q_header: String = (0..nq)
- .map(|i| format!("{:^width$}", format!("q{}", i), width = col_width))
- .collect::<Vec<_>>()
- .join(" ");
-
- let c_header: String = (0..nc)
- .map(|i| format!("{:^width$}", format!("c{}", i), width = col_width))
- .collect::<Vec<_>>()
- .join(" ");
-
- if nc > 0 {
- writeln!(f, "{}{}{}", q_header, " ".repeat(gap_width), c_header)?;
- } else {
- writeln!(f, "{}", q_header)?;
- }
-
- let q_wires: String = (0..nq)
- .map(|_| format!("{:^width$}", "│", width = col_width))
- .collect::<Vec<_>>()
- .join(" ");
-
- let c_wires: String = (0..nc)
- .map(|_| format!("{:^width$}", "║", width = col_width))
- .collect::<Vec<_>>()
- .join(" ");
-
- let full_wires = if nc > 0 {
- format!("{}{}{}", q_wires, " ".repeat(gap_width), c_wires)
- } else {
- q_wires.clone()
- };
-
- if ops.is_empty() {
- writeln!(f, "{}", full_wires)?;
- return Ok(());
- }
-
- let q_total = nq * col_width + (nq - 1);
- let c_total = if nc > 0 { nc * col_width + (nc - 1) } else { 0 };
- let total_width = q_total + gap_width + c_total;
-
- for op in ops {
- writeln!(f, "{}", full_wires)?;
-
- let q_targets = op.quantum_targets();
- let min_q = q_targets.iter().min().copied().unwrap_or(0);
- let max_q = q_targets.iter().max().copied().unwrap_or(0);
-
- let label = Self::gate_label(op);
-
- match op {
- GateOp::H(t)
- | GateOp::X(t)
- | GateOp::Y(t)
- | GateOp::Z(t)
- | GateOp::S(t)
- | GateOp::T(t)
- | GateOp::Sdg(t)
- | GateOp::Tdg(t)
- | GateOp::Sx(t)
- | GateOp::Sxdg(t)
- | GateOp::Rx(t, _)
- | GateOp::Ry(t, _)
- | GateOp::Rz(t, _)
- | GateOp::P(t, _)
- | GateOp::U1(t, _)
- | GateOp::U2(t, _, _)
- | GateOp::U3(t, _, _, _) => {
- let mut line: Vec<char> = vec![' '; total_width];
-
- for i in 0..nq {
- let col_start = i * (col_width + 1);
- let center = col_start + col_width / 2;
- if i == *t {
- let label_start = col_start + (col_width - label.chars().count()) / 2;
- for (j, ch) in label.chars().enumerate() {
- line[label_start + j] = ch;
- }
- } else {
- line[center] = '│';
- }
- }
-
- for i in 0..nc {
- let center = q_total + gap_width + i * (col_width + 1) + col_width / 2;
- line[center] = '║';
- }
-
- let gate_line: String = line.into_iter().collect();
- writeln!(f, "{}", gate_line)?;
- }
- GateOp::CNOT(c, t) | GateOp::CZ(c, t) | GateOp::SWAP(c, t)
- | GateOp::CRx(c, t, _) | GateOp::CRy(c, t, _) | GateOp::CRz(c, t, _) | GateOp::CP(c, t, _) => {
- let (sym1, sym2) = match op {
- GateOp::CNOT(_, _) => ('●', '⊕'),
- GateOp::CZ(_, _) => ('●', '●'),
- GateOp::SWAP(_, _) => ('╳', '╳'),
- GateOp::CRx(_, _, _) | GateOp::CRy(_, _, _) | GateOp::CRz(_, _, _) | GateOp::CP(_, _, _) => ('●', '□'),
- _ => unreachable!(),
- };
-
- let mut line: Vec<char> = vec![' '; total_width];
-
- for i in 0..nq {
- let col_start = i * (col_width + 1);
- let center = col_start + col_width / 2;
- if i < min_q || i > max_q {
- line[center] = '│';
- } else if i == *c {
- line[center] = sym1;
- } else if i == *t {
- // For controlled parametric gates, show the gate label on target
- if matches!(op, GateOp::CRx(_, _, _) | GateOp::CRy(_, _, _) | GateOp::CRz(_, _, _) | GateOp::CP(_, _, _)) {
- let label_start = col_start + (col_width - label.chars().count()) / 2;
- for (j, ch) in label.chars().enumerate() {
- if label_start + j < line.len() {
- line[label_start + j] = ch;
- }
- }
- } else {
- line[center] = sym2;
- }
- }
- }
-
- let min_center = min_q * (col_width + 1) + col_width / 2;
- let max_center = max_q * (col_width + 1) + col_width / 2;
- for pos in (min_center + 1)..max_center {
- if line[pos] == ' ' {
- line[pos] = '─';
- }
- }
-
- for i in 0..nc {
- let center = q_total + gap_width + i * (col_width + 1) + col_width / 2;
- line[center] = '║';
- }
-
- let gate_line: String = line.into_iter().collect();
- writeln!(f, "{}", gate_line)?;
- }
- GateOp::CCNOT(c1, c2, t) | GateOp::CSWAP(c1, c2, t) => {
- let (sym_c, sym_t) = match op {
- GateOp::CCNOT(_, _, _) => ('●', '⊕'),
- GateOp::CSWAP(_, _, _) => ('●', '╳'),
- _ => unreachable!(),
- };
- let is_cswap = matches!(op, GateOp::CSWAP(_, _, _));
-
- let mut line: Vec<char> = vec![' '; total_width];
-
- for i in 0..nq {
- let center = i * (col_width + 1) + col_width / 2;
- if i < min_q || i > max_q {
- line[center] = '│';
- } else if i == *c1 {
- line[center] = sym_c;
- } else if i == *c2 {
- line[center] = if is_cswap { sym_t } else { sym_c };
- } else if i == *t {
- line[center] = sym_t;
- }
- }
-
- let min_center = min_q * (col_width + 1) + col_width / 2;
- let max_center = max_q * (col_width + 1) + col_width / 2;
- for pos in (min_center + 1)..max_center {
- if line[pos] == ' ' {
- line[pos] = '─';
- }
- }
-
- for i in 0..nc {
- let center = q_total + gap_width + i * (col_width + 1) + col_width / 2;
- line[center] = '║';
- }
-
- let gate_line: String = line.into_iter().collect();
- writeln!(f, "{}", gate_line)?;
- }
- GateOp::Measure(mq, mc) => {
- let mut line: Vec<char> = vec![' '; total_width];
-
- for i in 0..nq {
- let col_start = i * (col_width + 1);
- let center = col_start + col_width / 2;
- if i < *mq {
- line[center] = '│';
- } else if i == *mq {
- let label_start = col_start + (col_width - label.chars().count()) / 2;
- for (j, ch) in label.chars().enumerate() {
- line[label_start + j] = ch;
- }
- }
- }
-
- let mq_col_start = *mq * (col_width + 1);
- let mq_center = mq_col_start + col_width / 2;
- let mc_start = q_total + gap_width;
- let mc_center = mc_start + *mc * (col_width + 1) + col_width / 2;
-
- for pos in (mq_center + 2)..=mc_center {
- if line[pos] == ' ' {
- line[pos] = '═';
- }
- }
- line[mc_center] = '╣';
-
- for i in 0..nc {
- let center = mc_start + i * (col_width + 1) + col_width / 2;
- if i > *mc {
- line[center] = '║';
- }
- }
-
- let measure_line: String = line.into_iter().collect();
- writeln!(f, "{}", measure_line)?;
- }
- GateOp::Custom(_, targets) => {
- let mut line: Vec<char> = vec![' '; total_width];
-
- if targets.len() == 1 {
- for i in 0..nq {
- let col_start = i * (col_width + 1);
- let center = col_start + col_width / 2;
- if i == targets[0] {
- let label_start =
- col_start + (col_width - label.chars().count()) / 2;
- for (j, ch) in label.chars().enumerate() {
- line[label_start + j] = ch;
- }
- } else {
- line[center] = '│';
- }
- }
-
- for i in 0..nc {
- let center = q_total + gap_width + i * (col_width + 1) + col_width / 2;
- line[center] = '║';
- }
- } else {
- for i in 0..nq {
- let col_start = i * (col_width + 1);
- let center = col_start + col_width / 2;
- if i < min_q || i > max_q {
- line[center] = '│';
- } else if i == targets[0] {
- let label_start =
- col_start + (col_width - label.chars().count()) / 2;
- for (j, ch) in label.chars().enumerate() {
- line[label_start + j] = ch;
- }
- } else if targets.contains(&i) {
- line[center] = '□';
- }
- }
-
- let min_center = min_q * (col_width + 1) + col_width / 2;
- let max_center = max_q * (col_width + 1) + col_width / 2;
- for pos in (min_center + 1)..max_center {
- if line[pos] == ' ' {
- line[pos] = '─';
- }
- }
-
- for i in 0..nc {
- let center = q_total + gap_width + i * (col_width + 1) + col_width / 2;
- line[center] = '║';
- }
- }
-
- let gate_line: String = line.into_iter().collect();
- writeln!(f, "{}", gate_line)?;
- }
- }
- }
-
- writeln!(f, "{}", full_wires)?;
-
- let end_line: String = "░".repeat(total_width);
- writeln!(f, "{}", end_line)?;
-
- Ok(())
- }
-}
diff --git a/libpsi-visualizer/src/cli/visualizer.rs b/libpsi-visualizer/src/cli/visualizer.rs
deleted file mode 100644
index 33f730f..0000000
--- a/libpsi-visualizer/src/cli/visualizer.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub trait Visualizer {
- fn export(&self) -> String;
-}
diff --git a/libpsi-visualizer/src/lib.rs b/libpsi-visualizer/src/lib.rs
deleted file mode 100644
index 373ae6d..0000000
--- a/libpsi-visualizer/src/lib.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-pub mod cli;
-pub use cli::*;