#[cfg(feature = "hints")]
use crate::util::events;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Hint {
pub indent: usize,
pub text: String,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Hints(pub Vec<Hint>);
impl Hints {
pub fn new() -> Self {
Hints(Vec::new())
}
}
#[cfg(feature = "hints")]
struct InterimHints {
current_indent: usize,
hints: Hints,
}
#[cfg(feature = "hints")]
impl events::Events for InterimHints {
fn new() -> Self {
InterimHints {
current_indent: 0,
hints: Hints::new(),
}
}
fn take(&mut self) -> Self {
InterimHints {
current_indent: self.current_indent,
hints: Hints(self.hints.0.drain(..).collect()),
}
}
}
#[cfg(feature = "hints")]
thread_local! {
static LOCAL: events::Stack<InterimHints> = events::new_stack();
}
pub fn collect<R>(f: impl FnOnce() -> R) -> (R, Hints) {
#[cfg(feature = "hints")]
{
let (result, interim) = events::collect(&LOCAL, f);
(result, interim.hints)
}
#[cfg(not(feature = "hints"))]
{
(f(), Hints::new())
}
}
pub fn enabled() -> bool {
#[cfg(feature = "hints")]
{
events::enabled(&LOCAL)
}
#[cfg(not(feature = "hints"))]
{
false
}
}
pub fn add(message_text: impl FnOnce() -> String) {
#[cfg(feature = "hints")]
{
events::modify(&LOCAL, move |stack| {
let text = message_text();
let len = stack.len();
fn add_message(interim: &mut InterimHints, text: String) {
let indent = interim.current_indent;
let message = Hint { indent, text };
interim.hints.0.push(message);
}
stack[0..len - 1]
.iter_mut()
.for_each(|collection| add_message(collection, text.clone()));
add_message(&mut stack[len - 1], text);
});
}
#[cfg(not(feature = "hints"))]
{
let _ = message_text;
}
}
pub fn indent() {
#[cfg(feature = "hints")]
{
events::modify(&LOCAL, |stack| {
stack.iter_mut().for_each(|interim| {
let current_indent = interim.current_indent;
interim.current_indent = current_indent.saturating_add(1);
});
});
}
}
pub fn unindent() {
#[cfg(feature = "hints")]
{
events::modify(&LOCAL, |stack| {
stack.iter_mut().for_each(|interim| {
let current_indent = interim.current_indent;
interim.current_indent = current_indent.saturating_sub(1);
});
});
}
}
pub struct Section {
_dummy: (),
}
impl Section {
pub fn start() -> Section {
indent();
Section { _dummy: () }
}
}
impl Drop for Section {
fn drop(&mut self) {
unindent();
}
}