use std::collections::HashMap;
use std::path::Path;
use serde::de::DeserializeOwned;
use crate::MartinError;
use crate::config::file::parse_config;
use crate::logging::LogFormat;
pub(crate) fn parse_yaml<T: DeserializeOwned>(yaml: &str) -> T {
let opts = serde_saphyr::options! {
with_snippet: false,
};
serde_saphyr::from_str_with_options::<T>(yaml, opts)
.unwrap_or_else(|e| panic!("expected `{yaml}` to parse, but got error:\n{e}"))
}
pub(crate) fn render_failure(yaml: &str) -> String {
let env: HashMap<String, String> = HashMap::new();
let err = parse_config(yaml, &env, Path::new("config.yaml"))
.err()
.unwrap_or_else(|| panic!("expected configuration to fail to parse:\n{yaml}"));
let rendered = MartinError::ConfigFileError(err).render_diagnostic();
strip_ansi(&rendered)
}
pub(crate) fn render_failure_json(yaml: &str) -> String {
let env: HashMap<String, String> = HashMap::new();
let err = parse_config(yaml, &env, Path::new("config.yaml"))
.err()
.unwrap_or_else(|| panic!("expected configuration to fail to parse:\n{yaml}"));
MartinError::ConfigFileError(err).render_diagnostic_with(LogFormat::Json)
}
fn strip_ansi(s: &str) -> String {
let mut out = String::with_capacity(s.len());
let mut chars = s.chars();
while let Some(c) = chars.next() {
if c == '\x1b' {
if let Some('[') = chars.next() {
for nc in chars.by_ref() {
if ('@'..='~').contains(&nc) {
break;
}
}
}
continue;
}
out.push(c);
}
out
}