use std::fmt::{Debug, Display}; use crate::prelude::*; use Value as V; impl Debug for Value { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { V::Nil => write!(f, "[Nil]"), V::Int(i) => write!(f, "[Int {i}]"), V::Bool(b) => write!(f, "[Bool {b}]"), V::Float(vf) => write!(f, "[Float {vf}]"), V::Ratio(r) => write!(f, "[Ratio {r}]"), V::Complex(c) => write!(f, "[Complex {c}]"), V::Regex(r) => write!(f, "[Regex /{r}/]"), V::String(s) => write!(f, "[String '{s}']"), V::List(l) => write!(f, "[List {}]", l.len()), V::Matrix(m) => write!(f, "[Matirx {}x{}]", m.domain, m.codomain), V::Table(t) => write!(f, "[Table {}]", t.len()), V::Function(vf) => write!(f, "[Function {}]", vf.name), V::Range(r) => write!(f, "[Range {:?}..{:?}]", r.0, r.1), V::Iter(_) => write!(f, "[Iterator]"), V::Exception(_) => write!(f, "[Error]"), V::File(_) => write!(f, "[File]"), } } } impl Display for Value { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let red; let green; let yellow; let blue; let pink; let cyan; let clear; if f.alternate() { red = "\x1b[31m"; green = "\x1b[32m"; yellow = "\x1b[33m"; blue = "\x1b[34m"; pink = "\x1b[35m"; cyan = "\x1b[36m"; clear = "\x1b[0m"; } else { red = ""; green = ""; yellow = ""; blue = ""; pink = ""; cyan = ""; clear = ""; } match self { V::Nil => {write!(f, "{blue}nil{clear}")?;}, V::Bool(b) => {write!(f, "{yellow}{b}{clear}")?;}, V::Int(i) => {write!(f, "{yellow}{i}{clear}")?;}, V::Float(l) => {write!(f, "{yellow}{l}{clear}")?;}, V::Ratio(r) => {write!(f, "{yellow}{r}{clear}")?;}, V::Complex(c) => {write!(f, "{yellow}{c}{clear}")?;}, V::Regex(r) => {write!(f, "/{red}{r}{clear}/")?;}, V::String(s) => { if f.alternate() { write!(f, "{green}'{s}'{clear}")?; } else { write!(f, "{s}")?; } } V::List(l) => { if l.len() < 1 { write!(f, "[]")?; return Ok(()) } write!(f, "[ ")?; for (i, el) in l.iter().enumerate() { if i != 0 { write!(f, " ")?; } if f.alternate() { write!(f, "{el:#}")?; } else { write!(f, "{el}")?; } } write!(f, " ]")?; }, V::Matrix(m) => { if f.alternate() { write!(f, "{m:#}")?; } else { write!(f, "{m}")?; } }, V::Table(t) => { if f.alternate() { write!(f, "{t:#}")?; } else { write!(f, "{t}")?; } }, V::Function(fun) => { write!(f, "{cyan}{fun}{clear}")?; } V::Range(r) => { if f.alternate() { write!(f, "{:#}..{:#}", r.0, r.1)?; } else { write!(f, "{}..{}", r.0, r.1)?; } } V::Iter(_) => {write!(f, "{pink}[Iterator]{clear}")?;}, V::File(_) => {write!(f, "{pink}[File]{clear}")?;}, V::Exception(e) => {write!(f, "{red}{e}{clear}")?;}, }; Ok(()) } } impl Debug for Matrix { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "[Matrix {}x{}]", self.domain, self.codomain) } } impl Display for Matrix { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut max_cols = vec![0; self.domain]; let mut vals: Vec = Vec::with_capacity(self.domain * self.codomain); for row in 0..self.codomain { for col in 0..self.domain { let idx = col + row * self.domain; let el = &self.values[idx]; let s = match f.alternate() { true => format!("{:#}", el), false => format!("{}", el) }; max_cols[col] = max_cols[col].max(s.len()); vals.push(s); } } write!(f, "\n")?; for row in 0..self.codomain { for col in 0..self.domain { let idx = col + row * self.domain; let s = vals[idx].as_str(); let width = max_cols[col]; write!(f, " {s:>width$}")?; } write!(f, "\n")?; } Ok(()) } } impl Debug for ValueMap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "[Table {}]", self.len()) } } impl Display for ValueMap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if self.len() < 1 { write!(f, "{{}}")?; return Ok(()) } write!(f, "{{ ")?; for (i, (key, value)) in self.entries().enumerate() { if i != 0 { write!(f, ", ")?; } if f.alternate() { write!(f, "{key:#} = {value:#}")? } else { write!(f, "{key} = {value}")? } } write!(f, " }}")?; Ok(()) } }