use super::Formatter;
use crate::highlight;
use crate::languages::Language;
use crate::themes::Theme;
use derive_builder::Builder;
pub use lumis_core::formatter::terminal::Background;
use lumis_core::formatter::Formatter as _;
use std::io::{self, Write};
#[derive(Builder, Clone, Debug)]
#[builder(default)]
pub struct Terminal {
#[builder(setter(custom))]
language: Language,
theme: Option<Theme>,
background: Background,
width: Option<usize>,
}
impl TerminalBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn language(&mut self, language: Language) -> &mut Self {
self.language = Some(language);
self
}
#[deprecated(note = "use `.language(...)` instead")]
pub fn lang(&mut self, language: Language) -> &mut Self {
self.language(language)
}
}
impl Terminal {
pub fn new(
language: Language,
theme: Option<Theme>,
background: Background,
width: Option<usize>,
) -> Self {
Self {
language,
theme,
background,
width,
}
}
}
impl Default for Terminal {
fn default() -> Self {
Self {
language: Language::PlainText,
theme: None,
background: Background::Inherit,
width: None,
}
}
}
impl Formatter for Terminal {
fn format(&self, source: &str, output: &mut dyn Write) -> io::Result<()> {
let events =
highlight::highlight_events(source, self.language).map_err(io::Error::other)?;
let core_formatter = lumis_core::formatter::terminal::Terminal::new(
self.language,
self.theme.clone(),
self.background.clone(),
self.width,
);
core_formatter.render(source, &events, output)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_no_attrs() {
let code = "@lang :rust";
let formatter = Terminal::new(Language::Elixir, None, Background::Inherit, None);
let mut buffer = Vec::new();
formatter.format(code, &mut buffer).unwrap();
let result = String::from_utf8_lossy(&buffer);
assert!(result.contains("@"));
assert!(result.contains("lang"));
assert!(result.contains(":rust"));
}
}