use nu_ansi_term::{AnsiString, AnsiStrings};
use rink_core::output::fmt::{FmtToken, Span, TokenFmt};
use crate::config::{Config, Theme};
fn to_ansi_inner<'a>(
theme: &Theme,
long_output: bool,
mut indent: usize,
strings: &mut Vec<AnsiString<'a>>,
obj: &'a dyn TokenFmt<'a>,
) {
let spans = obj.to_spans();
let mut nothing_printed = true;
for span in spans {
match span {
Span::Content {
token: FmtToken::ListBegin,
text,
} if long_output => {
indent += 1;
if text.is_empty() && nothing_printed {
strings.push(format!("{:width$}• ", "", width = indent * 2 - 2).into());
} else {
strings.push(text.into());
strings.push(format!("\n{:width$}• ", "", width = indent * 2 - 2).into());
}
nothing_printed = false;
}
Span::Content {
token: FmtToken::ListSep,
..
} if long_output => {
nothing_printed = false;
strings.push(format!("\n{:width$}• ", "", width = indent * 2 - 2).into());
}
Span::Content {
text,
token: token @ FmtToken::DateTime,
} => {
let datetime = jiff::civil::DateTime::strptime("%Y-%m-%d %H:%M:%S", &*text);
let date = jiff::civil::Date::strptime("%Y-%m-%d", &*text);
nothing_printed = false;
if let Ok(date) = datetime {
strings.push(
theme
.get_style(token)
.paint(date.strftime("%B %-d, %Y %H:%M:%S").to_string()),
);
} else if let Ok(date) = date {
strings.push(
theme
.get_style(token)
.paint(date.strftime("%B %-d, %Y").to_string()),
);
} else {
strings.push(theme.get_style(token).paint(text));
}
}
Span::Content {
text,
token: token @ FmtToken::Link,
} => {
nothing_printed = false;
strings.push(theme.get_style(token).paint(text.clone()).hyperlink(text));
}
Span::Content { text, token } => {
nothing_printed = false;
strings.push(theme.get_style(token).paint(text));
}
Span::Child(obj) => {
nothing_printed = false;
to_ansi_inner(theme, long_output, indent, strings, obj);
}
}
}
}
pub fn to_ansi<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> Vec<AnsiString<'a>> {
let mut strings = vec![];
to_ansi_inner(
config.get_theme(),
config.rink.long_output,
0,
&mut strings,
obj,
);
strings
}
pub fn to_ansi_string<'a>(config: &Config, obj: &'a dyn TokenFmt<'a>) -> String {
let strings = to_ansi(config, obj);
let strings = AnsiStrings(&strings);
format!("{}", strings)
}