mod api_doc;
mod axum;
mod axum_shared;
mod dto;
mod endpoint;
mod feature;
mod files;
mod framework;
mod handlers;
mod layout;
pub mod listing;
mod operation;
mod paths;
mod prechecks;
mod relation_routes;
mod relation_service;
mod relations;
mod root;
mod rule_functions;
mod rule_snippets;
mod rule_tables;
mod rules;
mod schemas;
mod scope;
mod search;
mod service;
pub mod shared;
mod shared_validation;
mod unique;
use std::path::PathBuf;
use self::feature::Endpoint;
pub use self::feature::Feature;
use crate::ApiConfig;
use crate::schema::Table;
pub fn features<'a>(tables: &'a [Table], api: &'a ApiConfig) -> Result<Vec<Feature<'a>>, String> {
let mut features = Vec::new();
for table in tables {
features.extend(Feature::of(table, api, tables)?);
}
let relations: Vec<_> = features
.iter()
.map(|feature| relations::relations(feature, &features, tables, api))
.collect();
let references: Vec<_> = features
.iter()
.map(|feature| prechecks::references(feature, &features, tables))
.collect();
for ((feature, relations), references) in features.iter_mut().zip(relations).zip(references) {
feature.relations = relations;
feature.references = references;
feature.unique_checks = unique::checks(feature);
}
Ok(features)
}
pub fn has_listing(feature: &Feature<'_>) -> bool {
feature.serves(Endpoint::List)
|| feature.serves(Endpoint::Search)
|| feature.reads_owned_rows()
|| !feature.unique_checks.is_empty()
|| feature
.relations
.iter()
.any(|relation| relation.writes().is_some())
}
pub fn render(features: &[Feature<'_>], api: &ApiConfig) -> Vec<(PathBuf, String)> {
let root = api.output.as_path();
let mut files = Vec::new();
for feature in features {
let dir = root.join(feature.module());
files.extend([
(dir.join("mod.rs"), files::render_mod(feature)),
(dir.join("routes.rs"), handlers::render_routes(feature)),
(dir.join("handlers.rs"), handlers::render_handlers(feature)),
(dir.join("dto.rs"), dto::render(feature)),
(dir.join("model.rs"), files::render_model(feature)),
(dir.join("repo.rs"), files::render_repo(feature)),
(dir.join("service_api.rs"), service::render_api(feature)),
(dir.join("service.rs"), service::render_scaffold(feature)),
]);
}
files.push((
root.join("generated.rs"),
root::render_generated(features, api),
));
files.push((
root.join("README.md"),
root::render_readme(features, api.framework),
));
files
}
pub fn owned_dirs(api: &ApiConfig) -> [PathBuf; 2] {
[api.output.clone(), shared::shared_dir(api)]
}