cargo-plot 0.3.0-beta.3

Szwajcarski scyzoryk do wizualizacji struktury projektu i generowania dokumentacji bezpoΕ›rednio z poziomu Cargo.
Documentation
use super::Color;
use crate::lib::logic::{JobMode, JobSpec, TabSortOrder};

impl std::fmt::Display for JobSpec {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		let name = self.name.as_deref().unwrap_or("None");
		let desc = self.description.as_deref().unwrap_or("None");

		let quiet_status = if self.quiet_work { "πŸ”‡ (Quiet)" } else { "πŸ”Š (Verbose)" };

		// Helpery do kolorowania zmiennych, aby utrzymać czystość makr
		let c_bool = |b: bool| Color::size(&b.to_string()).to_string();
		let c_num = |n: usize| Color::size(&n.to_string()).to_string();

		println!("{}", "β–‘".repeat(80));
		// --- NAGŁÓWEK ---
		writeln!(f, "【IDγ€‘πŸ”– [{}] | {} | {}", Color::num(&self.id), Color::folder(name), quiet_status)?;
		writeln!(f, "  β”‚   πŸ“œ {}", Color::border(desc))?;
		writeln!(f, "  β”‚")?;

		// --- SEKCJA SCAN ---
		writeln!(f, "  β”œβ”€β”€γ€SCAN】")?;
		writeln!(f, "  β”‚    β”œβ”€β”€ 🎯 \"{}\"", Color::folder(&self.scan.work_path))?;
		writeln!(f, "  β”‚    └── πŸ”Ž | πŸš«πŸ”  [{}]", c_bool(self.scan.ignore_case))?;

		let pats_len = self.scan.patterns.len();
		for (i, pat) in self.scan.patterns.iter().enumerate() {
			let branch = if i == pats_len - 1 { "└──" } else { "β”œβ”€β”€" };
			writeln!(f, "  β”‚        {} \"{}\"", branch, Color::border(pat))?;
		}

		writeln!(f, "  β”‚")?;

		// --- SEKCJA EXPORT ---
		writeln!(f, "  β”œβ”€β”€γ€EXPORT】")?;
		let has_sotc = self.save_sotc_at.is_some();
		let sotc_path = self.save_sotc_at.as_deref().unwrap_or("");
		let sotc_title = self.title_sotc.as_deref().unwrap_or("");
		writeln!(f, "  β”‚    β”œβ”€β”€γ€SOTCγ€‘πŸ—ƒοΈ  [{}] | πŸ’Ύ \"{}\"", c_bool(has_sotc), Color::folder(sotc_path))?;
		writeln!(f, "  β”‚    β”‚    └── πŸ”€ \"{}\"", Color::border(sotc_title))?;

		let has_cots = self.save_cots_at.is_some();
		let cots_path = self.save_cots_at.as_deref().unwrap_or("");
		let cots_title = self.title_cots.as_deref().unwrap_or("");
		writeln!(f, "  β”‚    └──【COTSγ€‘πŸ“š [{}] | πŸ’Ύ \"{}\"", c_bool(has_cots), Color::folder(cots_path))?;
		writeln!(f, "  β”‚         └── πŸ”€ \"{}\"", Color::border(cots_title))?;

		writeln!(f, "  β”‚")?;

		// --- SEKCJA TABLE ---
		writeln!(f, "  β”œβ”€β”€γ€TABLE】")?;
		let cols = self.table.columns.iter().map(|c| format!("{:?}", c)).collect::<Vec<_>>().join(", ");
		let struct_name = format!("{:?}", self.table.structure);
		writeln!(
			f,
			"  β”‚    β”œβ”€β”€ 🧩 [{}] | πŸ—οΈ  [{}] | βž• [{}]",
			Color::size(&cols),
			Color::size(&struct_name),
			c_bool(self.table.more_icons)
		)?;

		let sort_by_str = format!("{:?}", self.table.sort_by).to_lowercase();
		let sort_order_str = format!("{:?}", self.table.sort_order).to_lowercase();
		let is_reverse = self.table.sort_order == TabSortOrder::Desc;
		writeln!(
			f,
			"  β”‚    └── πŸ“Ά (\"{}\", \"{}\") | ↩️  [{}]",
			Color::size(&sort_by_str),
			Color::size(&sort_order_str),
			c_bool(is_reverse)
		)?;

		writeln!(f, "  β”‚")?;

		// --- SEKCJA SPEC ---
		writeln!(f, "  └──【SPEC】")?;
		let is_m = self.mode == JobMode::Matched;
		let is_x = self.mode == JobMode::Mismatched;
		writeln!(f, "       β”œβ”€β”€ βš™οΈ βœ”οΈ  Matched [{}] | βš™οΈ βœ–οΈ  Mismatched [{}]", c_bool(is_m), c_bool(is_x))?;
		writeln!(f, "       β”œβ”€β”€ πŸ™ˆπŸ“Š [{}] | πŸ™ˆβ„ΉοΈ  [{}]", c_bool(self.hide_stats), c_bool(self.hide_promo))?;

		let is_trim = self.table.trim_size.is_some();
		let t_size = self.table.trim_size.unwrap_or(20);
		let t_page = self.table.trim_page;

		write!(f, "       └── βœ‚οΈ πŸ“ƒ [{}] | πŸ“„πŸ“ [{}] | πŸ“„πŸ‘οΈ  [{}] ", c_bool(is_trim), c_num(t_size), c_num(t_page))
	}
}