use axum::extract::{ConnectInfo, Path, State};
use axum::http::StatusCode;
use axum::response::Redirect;
use crate::service;
use crate::database;
pub(crate) async fn process(
State(state): State<service::State>,
Path(url_id_simple): Path<uuid::fmt::Simple>,
ConnectInfo(visitor_ip_addr): ConnectInfo<std::net::SocketAddr>,
header: hyper::HeaderMap,
) -> Result<Redirect, StatusCode> {
let url_id = url_id_simple.as_uuid().clone();
let url = database::url::fetch(&url_id, &state.pool)
.await
.map_err(|err| match err {
sqlx::Error::RowNotFound => StatusCode::NOT_FOUND,
_ => service::server_error(err, "Could not fetch URL"),
})?;
tokio::spawn(async move {
database::visit::log(&url_id, &visitor_ip_addr, &header, &state.pool)
.await
.inspect_err(|err| {
eprintln!("[ERROR] Visit dropped on {url_id}: {err}");
})
});
Ok(Redirect::temporary(url.as_str()))
}