imap-tools 1.8.2

A collection of tools to manipulate IMAP mailboxes
use crate::libs::render::{Renderer as RendererTrait, RendererError};
use exn::{Result, ResultExt as _};
use std::{collections::HashMap, fmt::Display};
use strfmt::strfmt;

#[cfg_attr(feature = "tracing", derive(Debug))]
pub struct Renderer<'a> {
    format: &'a str,
    headers: Vec<&'a str>,
    some_output: bool,
}

impl RendererTrait for Renderer<'_> {
    #[cfg_attr(
        feature = "tracing",
        tracing::instrument(
            level = "trace",
            skip(_title, format, headers),
            ret,
            err(level = "info")
        )
    )]
    fn new(
        _title: &'static str,
        format: &'static str,
        headers: &[&'static str],
    ) -> Result<Self, RendererError> {
        Ok(Self {
            format,
            headers: headers.into(),
            some_output: false,
        })
    }

    #[cfg_attr(
        feature = "tracing",
        tracing::instrument(level = "trace", skip(self, row), err(level = "info"))
    )]
    #[expect(clippy::print_stdout, reason = "we print")]
    fn add_row(&mut self, row: &[&dyn Display]) -> Result<(), RendererError> {
        #[cfg(feature = "tracing")]
        tracing::trace!(row = ?row.iter().map(std::string::ToString::to_string).collect::<Vec<_>>());

        if !self.some_output {
            self.some_output = true;

            let map: HashMap<_, _> = self
                .headers
                .iter()
                .enumerate()
                .map(|(idx, f)| (idx, *f))
                .collect();
            let output = strfmt(self.format, &map)
                .or_raise(|| RendererError(format!("strfmt failed {:?} {:?}", self.format, map)))?;
            println!("{output}");
        }
        let map: HashMap<_, _> = row
            .iter()
            .enumerate()
            .map(|(idx, f)| (idx, f.to_string()))
            .collect();
        let output = strfmt(self.format, &map)
            .or_raise(|| RendererError(format!("strfmt failed {:?} {:?}", self.format, map)))?;
        println!("{output}");

        Ok(())
    }
}