use crate::attribute_routes::extract_attribute_routes;
use crate::routes_php::extract_routes_php;
use glob::{glob, GlobError, Paths, Pattern};
use std::fs::read_to_string;
use std::path::{Path, PathBuf};
use thiserror::Error;
mod attribute_routes;
mod route;
mod routes_php;
pub use route::*;
pub fn core_routes(path: &str) -> Result<AppRoutes, Error> {
let mut result = AppRoutes {
routes: vec![
Route {
url: "/core/ajax/update.php".into(),
name: "core#ajax_update".into(),
..Route::default()
},
Route {
url: "/heartbeat".into(),
name: "core#heartbeat".into(),
..Route::default()
},
],
ocs: vec![],
};
let controller_paths = glob(&format!(
"{}/core/Controller/*Controller.php",
Pattern::escape(path)
))
.unwrap();
for routes in extract_controllers(controller_paths) {
let routes = routes?;
result.routes.extend_from_slice(&routes.routes);
result.ocs.extend_from_slice(&routes.ocs);
}
Ok(result)
}
pub fn app_routes(path: &str) -> Result<AppRoutes, Error> {
let routes_php_path = <str as AsRef<Path>>::as_ref(path).join("appinfo/routes.php");
let mut result = if routes_php_path.exists() {
let routes_php = read_to_string(&routes_php_path).map_err(|error| Error::Read {
path: routes_php_path.clone(),
error,
})?;
extract_routes_php(&routes_php_path, &routes_php)
} else {
AppRoutes::default()
};
let controller_paths = glob(&format!(
"{}/lib/Controller/*Controller.php",
Pattern::escape(path)
))
.unwrap();
for routes in extract_controllers(controller_paths) {
let routes = routes?;
result.routes.extend_from_slice(&routes.routes);
result.ocs.extend_from_slice(&routes.ocs);
}
Ok(result)
}
fn extract_controllers(paths: Paths) -> impl Iterator<Item = Result<AppRoutes, Error>> {
paths.map(|controller_path| {
let controller_path = controller_path.map_err(Error::Glob)?;
let controller_code = read_to_string(&controller_path).map_err(|error| Error::Read {
path: controller_path,
error,
})?;
Ok(extract_attribute_routes(&controller_code))
})
}
#[derive(Debug, Error)]
pub enum Error {
#[error("Failed to read {path}: {error:#}")]
Read {
path: PathBuf,
error: std::io::Error,
},
#[error("Failed to find controller paths: {0:#}")]
Glob(GlobError),
}