当我想抛出错误时,我有一个函数返回一个用
AppError
包裹的结构 Result
。
下面,我尝试抛出 401(未经授权)并显示消息“无效凭据”,但每次我打开代码时,我都必须编写
.ok_or()
来处理此问题。
pub async fn refresh_uses_session(
State(app_state): State<AppState>,
cookie_jar: CookieJar,
) -> Result<Response, AppError> {
let refresh_token_cookie = cookie_jar
.get("refresh_token")
.ok_or((StatusCode::UNAUTHORIZED, "Invalid Credentials").into_app_error())?;
let cookie_expiration_time = refresh_token_cookie
.expires()
.ok_or((StatusCode::UNAUTHORIZED, "Invalid Credentials").into_app_error())?
.datetime()
.ok_or((StatusCode::UNAUTHORIZED, "Invalid Credentials").into_app_error())?;
if cookie_expiration_time <= OffsetDateTime::now_utc() {
return Err((StatusCode::UNAUTHORIZED, "Invalid Credentials").into_app_error());
}
//…
}
有什么方法可以在不更改返回类型或辅助函数的情况下减少
.ok_or()
调用?
使用
Option
API,您应该能够使用 and_then
和 filter
函数将可选链滚动为单个值。
以下(非常简化的)示例应该可以说明我的意思:
struct Cookie {
expires: Option<String>,
}
struct CookieJar {
refresh_token: Option<Cookie>,
}
fn main() {
let result = test_function();
println!("{:?}", result);
}
fn test_function() -> Result<String, String> {
let cookie_jar = CookieJar { refresh_token: Some(Cookie { expires: None }) };
cookie_jar
.refresh_token
.and_then(|cookie| {cookie.expires})
.filter(|expiration| {expiration == "2024-04-28"})
.ok_or("My error message".to_string())
}