#[ allow( clippy ::std_instead_of_alloc, clippy ::std_instead_of_core ) ]
mod private
{
use std ::fmt ::Write;
use crate ::CrateDir;
use std ::fmt ::Formatter;
#[ derive( Debug, Clone, Eq, PartialEq ) ]
pub struct TreePrinter
{
symbols: Symbols,
pub info: ListNodeReport,
}
impl TreePrinter
{
#[ must_use ]
pub fn new(info: &ListNodeReport) -> Self
{
TreePrinter
{
symbols: Symbols ::default(),
info: info.clone(),
}
}
pub fn display_with_spacer( &self, spacer: &str ) -> Result< String, std ::fmt ::Error >
{
let mut f = String ::new();
write!( f, "{}", self.info.name )?;
if let Some( version ) = &self.info.version
{ write!( f, " {version}" )? }
if let Some( crate_dir ) = &self.info.crate_dir
{ write!( f, " {crate_dir}" )? }
if self.info.duplicate { write!( f, "(*)" )? }
writeln!( f )?;
let mut new_spacer = format!( "{spacer}{} ", if self.info.normal_dependencies.len() < 2 { " " } else { self.symbols.down } );
let mut normal_dependencies_iter = self.info.normal_dependencies.iter();
let last = normal_dependencies_iter.next_back();
for dep in normal_dependencies_iter
{
write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( dep ), &new_spacer )? )?;
}
if let Some( last ) = last
{
new_spacer = format!( "{spacer} " );
write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( last ), &new_spacer )? )?;
}
if !self.info.dev_dependencies.is_empty()
{
let mut dev_dependencies_iter = self.info.dev_dependencies.iter();
let last = dev_dependencies_iter.next_back();
writeln!( f, "{spacer}[dev-dependencies]" )?;
for dep in dev_dependencies_iter
{
write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( dep ), &new_spacer )? )?;
}
write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( last.unwrap() ), &new_spacer )? )?;
}
if !self.info.build_dependencies.is_empty()
{
let mut build_dependencies_iter = self.info.build_dependencies.iter();
let last = build_dependencies_iter.next_back();
writeln!( f, "{spacer}[build-dependencies]" )?;
for dep in build_dependencies_iter
{
write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( dep ), &new_spacer )? )?;
}
write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self ::display_with_spacer( &TreePrinter ::new( last.unwrap() ), &new_spacer )? )?;
}
Ok( f )
}
}
impl std ::fmt ::Display for TreePrinter
{
fn fmt( &self, f: &mut Formatter< '_ > ) -> std ::fmt ::Result
{
write!( f, "{}", self.display_with_spacer( "" )? )?;
Ok( () )
}
}
#[ derive( Debug, Clone, Eq, PartialEq ) ]
struct Symbols
{
down: &'static str,
tee: &'static str,
ell: &'static str,
right: &'static str,
}
impl Default for Symbols
{
fn default() -> Self
{
Self
{
down: "│",
tee: "├",
ell: "└",
right: "─",
}
}
}
#[ derive( Debug, Clone, Eq, PartialEq ) ]
pub struct ListNodeReport
{
pub name: String,
pub version: Option< String >,
pub crate_dir: Option< CrateDir >,
pub duplicate: bool,
pub normal_dependencies: Vec< ListNodeReport >,
pub dev_dependencies: Vec< ListNodeReport >,
pub build_dependencies: Vec< ListNodeReport >,
}
}
crate ::mod_interface!
{
orphan use TreePrinter;
orphan use ListNodeReport;
}