use anyhow::Result;
use bon::Builder;
#[cfg(feature = "color")]
use console::Style;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use std::io::Write;
#[cfg(feature = "trace")]
use tracing::Level;
#[derive(Builder, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
pub struct Prefix {
pub(crate) lines: Vec<String>,
#[cfg(feature = "color")]
#[cfg_attr(feature = "serde", serde(skip))]
#[cfg_attr(feature = "rkyv", rkyv(with = rkyv::with::Map<crate::pretty::feature::rkyv_support::StyleWith>))]
pub(crate) style: Option<Style>,
#[cfg(feature = "trace")]
#[builder(default = Level::INFO)]
#[cfg_attr(feature = "serde", serde(skip, default = "default_level"))]
#[cfg_attr(
feature = "rkyv",
rkyv(with = crate::pretty::feature::rkyv_support::LevelWith)
)]
pub(crate) level: Level,
}
impl Prefix {
pub(crate) fn display<T>(&self, writer: &mut T) -> Result<()>
where
T: Write + ?Sized,
{
self.inner_display(writer)?;
writeln!(writer)?;
Ok(())
}
#[cfg(not(feature = "color"))]
fn inner_display<T>(&self, writer: &mut T) -> Result<()>
where
T: Write + ?Sized,
{
for line in &self.lines {
writeln!(writer, "{line}")?;
}
Ok(())
}
}
#[cfg(all(feature = "serde", feature = "trace"))]
fn default_level() -> Level {
Level::INFO
}
#[cfg(test)]
mod test {
use crate::{Prefix, Pretty, utils::test_utils::TEST_PREFIX_SUFFIX, vergen_pretty_env};
use anyhow::Result;
use std::io::Write;
#[test]
#[allow(clippy::clone_on_copy, clippy::redundant_clone)]
fn prefix_clone_works() {
let prefix = Prefix::builder()
.lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
.build();
let another = prefix.clone();
assert_eq!(prefix, another);
}
#[test]
fn prefix_debug_works() -> Result<()> {
let prefix = Prefix::builder()
.lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
.build();
let mut buf = vec![];
write!(buf, "{prefix:?}")?;
assert!(!buf.is_empty());
Ok(())
}
#[test]
fn display_prefix_works() -> Result<()> {
let mut stdout = vec![];
let map = vergen_pretty_env!();
let prefix = Prefix::builder()
.lines(TEST_PREFIX_SUFFIX.lines().map(str::to_string).collect())
.build();
let fmt = Pretty::builder().env(map).prefix(prefix).build();
fmt.display(&mut stdout)?;
assert!(!stdout.is_empty());
Ok(())
}
}