use std::path::{Path, PathBuf};
use confique::meta::Meta;
use schemars::JsonSchema;
use super::{json5::render_json5_template, toml::render_toml_template, yaml::render_yaml_template};
use crate::{
config::{ConfigResult, ConfigSchema},
config_format::ConfigFormat,
config_schema::{generate::root_config_schema, paths::env_only_field_paths},
};
pub fn template_for_path<S>(path: impl AsRef<Path>) -> ConfigResult<String>
where
S: ConfigSchema + JsonSchema,
{
let full_schema = root_config_schema::<S>()?;
let env_only_paths = env_only_field_paths::<S>(&full_schema);
Ok(render_template(
ConfigFormat::from_path(path.as_ref()),
&S::META,
&[],
&[],
&[],
&env_only_paths,
))
}
pub(super) fn template_for_target<S>(
path: &Path,
include_paths: &[PathBuf],
section_path: &[&'static str],
split_paths: &[Vec<&'static str>],
env_only_paths: &[Vec<&'static str>],
) -> ConfigResult<String>
where
S: ConfigSchema,
{
Ok(render_template(
ConfigFormat::from_path(path),
&S::META,
include_paths,
section_path,
split_paths,
env_only_paths,
))
}
fn render_template(
format: ConfigFormat,
meta: &'static Meta,
include_paths: &[PathBuf],
section_path: &[&'static str],
split_paths: &[Vec<&'static str>],
env_only_paths: &[Vec<&'static str>],
) -> String {
match format {
ConfigFormat::Yaml => render_yaml_template(
meta,
include_paths,
section_path,
split_paths,
env_only_paths,
),
ConfigFormat::Toml => render_toml_template(
meta,
include_paths,
section_path,
split_paths,
env_only_paths,
),
ConfigFormat::Json => render_json5_template(
meta,
include_paths,
section_path,
split_paths,
env_only_paths,
),
}
}
pub(super) fn render_yaml_include(paths: &[PathBuf]) -> String {
let mut out = String::from("include:\n");
for path in paths {
out.push_str(" - ");
out.push_str("e_path(path));
out.push('\n');
}
out
}
pub(super) fn render_toml_include(paths: &[PathBuf]) -> String {
let entries = paths
.iter()
.map(|path| quote_path(path))
.collect::<Vec<_>>()
.join(", ");
format!("include = [{entries}]\n")
}
pub(super) fn render_json5_include(paths: &[PathBuf]) -> String {
let mut out = String::from(" include: [\n");
for path in paths {
out.push_str(" ");
out.push_str("e_path(path));
out.push_str(",\n");
}
out.push_str(" ],\n");
out
}
pub(super) fn quote_path(path: &Path) -> String {
serde_json::to_string(&path.to_string_lossy()).expect("path string serialization cannot fail")
}