rshtml_core 0.6.1

RsHtml: A Template Engine for Seamless HTML and Rust Integration.
Documentation
use crate::position::Position;
use std::path::Path;

#[derive(Debug, Default, Clone)]
pub struct Diagnostic<'a>(pub &'a str);

impl<'a> Diagnostic<'a> {
    pub fn message(
        &self,
        path: &Path,
        position: &Position,
        title: &str,
        info: &str,
        name_len: usize,
    ) -> String {
        let Some(source_snippet) = self.source_first_line(position) else {
            return String::new();
        };
        let line = position.0.0;
        let left_pad = line.to_string().len();
        let whitespace_len = source_snippet.len() - source_snippet.trim_start().len();
        let trimmed_col = position.0.1.saturating_sub(whitespace_len);

        let lp = " ".repeat(left_pad);
        let col_padding = " ".repeat(trimmed_col.saturating_sub(1));
        let file_info = self.files_to_info(path, position);
        let info = if info.is_empty() {
            "".to_string()
        } else {
            let hyphen = "^".repeat(name_len);
            format!("{lp} | {col_padding}{hyphen} {info}\n")
        };

        let lp = " ".repeat(left_pad - line.to_string().len());
        let source_snippet = source_snippet
            .trim_matches(|c| c == ' ' || c == '\t')
            .to_string();
        let source = format!("{lp}{line} | {source_snippet}\n");

        let title = if !title.is_empty() {
            format!("{title}\n")
        } else {
            String::new()
        };

        let lp = " ".repeat(left_pad);
        format!("{lp} --> {file_info}\n{title}{lp} |\n{source}{info}{lp} |",)
    }

    fn source_first_line(&self, position: &Position) -> Option<&str> {
        self.0.lines().nth((position.0).0.saturating_sub(1))
    }

    fn files_to_info(&self, path: &Path, position: &Position) -> String {
        position.as_info(path)
    }
}