use crate::contract::WorkerContract;
use super::error::AwlScaffoldError;
use super::plan::{ConnectionPlan, plan};
use super::{declaration_rs, handlers_rs, main_rs, manifest};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AionDependency {
Version(String),
Path(String),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DocumentRoot {
InCrateTree(String),
Absolute(String),
}
impl DocumentRoot {
#[must_use]
pub fn text(&self) -> &str {
match self {
Self::InCrateTree(path) | Self::Absolute(path) => path,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileOwnership {
Generated,
Author,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ScaffoldedFile {
pub relative: String,
pub contents: String,
pub ownership: FileOwnership,
}
#[derive(Debug, Clone)]
pub struct AwlWorkerScaffold<'a> {
pub contract: &'a WorkerContract,
pub crate_name: &'a str,
pub document_include: &'a str,
pub document_directory: &'a DocumentRoot,
pub document_name: &'a str,
pub dependencies: &'a AionDependency,
}
#[derive(Debug, Clone)]
pub struct WorkerScaffold {
pub plan: ConnectionPlan,
pub files: Vec<ScaffoldedFile>,
}
pub fn scaffold_awl_worker(
request: &AwlWorkerScaffold<'_>,
) -> Result<WorkerScaffold, AwlScaffoldError> {
validate_crate_name(request.crate_name)?;
validate_document_path(request.document_include, "document")?;
validate_document_path(request.document_directory.text(), "directory")?;
let plan = plan(request.contract)?;
let files = vec![
ScaffoldedFile {
relative: "Cargo.toml".to_owned(),
contents: manifest::emit(request, &plan),
ownership: FileOwnership::Generated,
},
ScaffoldedFile {
relative: "src/main.rs".to_owned(),
contents: main_rs::emit(request, &plan),
ownership: FileOwnership::Generated,
},
ScaffoldedFile {
relative: "src/declaration.rs".to_owned(),
contents: declaration_rs::emit(request, &plan),
ownership: FileOwnership::Generated,
},
ScaffoldedFile {
relative: "src/handlers.rs".to_owned(),
contents: handlers_rs::emit(&plan)?,
ownership: FileOwnership::Author,
},
];
Ok(WorkerScaffold { plan, files })
}
fn validate_crate_name(crate_name: &str) -> Result<(), AwlScaffoldError> {
let usable = !crate_name.is_empty()
&& crate_name.chars().all(|character| {
character.is_ascii_alphanumeric() || character == '-' || character == '_'
});
if usable {
return Ok(());
}
Err(AwlScaffoldError::CrateNameInvalid {
crate_name: crate_name.to_owned(),
})
}
fn validate_document_path(path: &str, role: &'static str) -> Result<(), AwlScaffoldError> {
if path.is_empty() {
return Err(AwlScaffoldError::DocumentPathEmpty { role });
}
Ok(())
}