mod common;
use axum_error_sets::{
ResultSetExt, StatusResultExt,
code::{Conflict, InternalServerError, NotFound, Unauthorized},
};
use common::{AppResultSet, StringError};
use rootcause::report;
fn app_error(msg: &'static str) -> Result<String, StringError> {
Err(StringError::new(msg))
}
fn generic_io_error() -> Result<(), std::io::Error> {
Err(std::io::Error::new(
std::io::ErrorKind::ConnectionReset,
"database socket reset",
))
}
fn fetch_user(id: &str) -> AppResultSet<String, (NotFound,)> {
if id != "valid_id" {
return app_error("user record not found")
.into_not_found()
.map_err(Into::into);
}
Ok(String::from("Alice"))
}
fn check_auth(token: &str) -> AppResultSet<(), (Unauthorized,)> {
if token.is_empty() {
app_error("missing auth token").into_unauthorized()?;
}
Ok(())
}
fn update_user_profile(
id: &str,
token: &str,
new_name: &str,
) -> AppResultSet<String, (Unauthorized, NotFound, Conflict, InternalServerError)> {
check_auth(token).into_superset()?;
let mut username = fetch_user(id).into_superset()?;
if new_name == "taken_username" {
return Err(Conflict(report!("username already taken")).into());
}
generic_io_error().into_internal()?;
username.push_str(" -> ");
username.push_str(new_name);
Ok(username)
}
fn main() {
println!(
"Failed Auth: {:?}",
update_user_profile("valid_id", "", "NewName")
);
println!(
"Failed Fetch: {:?}",
update_user_profile("invalid_id", "token123", "NewName")
);
println!(
"Conflict Error: {:?}",
update_user_profile("valid_id", "token123", "taken_username")
);
}