use std::fmt::Display;
use anyhow::anyhow;
use console::style;
use liquid::ValueView;
use crate::{
emoji, interactive, template::LiquidObjectResource, user_parsed_input::UserParsedInput,
};
use log::warn;
#[derive(Debug)]
pub struct ProjectNameInput(pub(crate) String);
impl TryFrom<(&LiquidObjectResource, &UserParsedInput)> for ProjectNameInput {
type Error = anyhow::Error;
fn try_from(
(liquid_object, user_parsed_input): (&LiquidObjectResource, &UserParsedInput),
) -> Result<Self, Self::Error> {
let name = liquid_object
.lock()
.unwrap()
.borrow()
.get("project-name")
.map(|v| {
let v = v.as_scalar().to_kstr().into_string();
if let Some(n) = user_parsed_input.name() {
if n != v {
warn!(
"{} `{}` {} `{}`{}",
style("Project name changed by template, from").bold(),
style(n).bold().yellow(),
style("to").bold(),
style(&v).bold().green(),
style("...").bold()
);
}
}
v
})
.or_else(|| user_parsed_input.name().map(String::from));
match name {
Some(name) => Ok(Self(name)),
None => {
match std::env::var("CARGO_GENERATE_VALUE_PROJECT_NAME") {
Ok(name) => Ok(Self(name)),
Err(_) if !user_parsed_input.silent() => Ok(Self(interactive::name()?)),
Err(_) => Err(anyhow!(
"{} {} {}",
emoji::ERROR,
style("Project Name Error:").bold().red(),
style("Option `--silent` provided, but project name was not set. Please use `--name`.")
.bold()
.red(),
)),
}
}
}
}
}
impl AsRef<str> for ProjectNameInput {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}
impl Display for ProjectNameInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}