From 9899c6f5aa07b671c94e6f02eb390663277ddecf Mon Sep 17 00:00:00 2001 From: Valentin Tolmer Date: Tue, 25 May 2021 10:03:33 +0200 Subject: [PATCH] app: Refactor API calls --- app/src/api.rs | 105 +++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/app/src/api.rs b/app/src/api.rs index 9982625..3e95476 100644 --- a/app/src/api.rs +++ b/app/src/api.rs @@ -22,30 +22,41 @@ fn get_claims_from_jwt(jwt: &str) -> Result { Ok(token.claims().clone()) } +fn create_handler( + callback: Callback>, + handler: F, +) -> Callback>> +where + F: Fn(http::StatusCode, Resp) -> Result + 'static, + Resp: std::fmt::Display, + CallbackResult: 'static, +{ + Callback::once(move |response: Response>| { + let (meta, maybe_data) = response.into_parts(); + let message = maybe_data + .map_err(|e| anyhow!("Could not reach server: {}", e)) + .and_then(|data| handler(meta.status, data)); + callback.emit(message) + }) +} + impl HostService { pub fn list_users( request: ListUsersRequest, callback: Callback>>, ) -> Result { let url = "/api/users"; - let handler = move |response: Response>| { - let (meta, maybe_data) = response.into_parts(); - let message = maybe_data - .map_err(|e| anyhow!("Could not fetch: {}", e)) - .and_then(|data| { - if meta.status.is_success() { - serde_json::from_str(&data) - .map_err(|e| anyhow!("Could not parse response: {}", e)) - } else { - Err(anyhow!("[{}]: {}", meta.status, data)) - } - }); - callback.emit(message) - }; let request = Request::post(url) .header("Content-Type", "application/json") .body(Json(&request))?; - FetchService::fetch_with_options(request, get_default_options(), handler.into()) + let handler = create_handler(callback, |status, data: String| { + if status.is_success() { + serde_json::from_str(&data).map_err(|e| anyhow!("Could not parse response: {}", e)) + } else { + Err(anyhow!("[{}]: {}", status, data)) + } + }); + FetchService::fetch_with_options(request, get_default_options(), handler) } pub fn authenticate( @@ -53,53 +64,37 @@ impl HostService { callback: Callback>, ) -> Result { let url = "/auth"; - let handler = move |response: Response>| { - let (meta, maybe_data) = response.into_parts(); - let message = maybe_data - .map_err(|e| anyhow!("Could not reach authentication server: {}", e)) - .and_then(|data| { - if meta.status.is_success() { - get_claims_from_jwt(&data) - .map_err(|e| anyhow!("Could not parse response: {}", e)) - .and_then(|jwt_claims| { - set_cookie("user_id", &jwt_claims.user, &jwt_claims.exp) - .map(|_| jwt_claims.user.clone()) - .map_err(|e| anyhow!("Error clearing cookie: {}", e)) - }) - } else if meta.status == 401 { - Err(anyhow!("Invalid username or password")) - } else { - Err(anyhow!( - "Could not authenticate: [{}]: {}", - meta.status, - data - )) - } - }); - callback.emit(message) - }; let request = Request::post(url) .header("Content-Type", "application/json") .body(Json(&request))?; - FetchService::fetch_with_options(request, get_default_options(), handler.into()) + let handler = create_handler(callback, |status, data: String| { + if status.is_success() { + get_claims_from_jwt(&data) + .map_err(|e| anyhow!("Could not parse response: {}", e)) + .and_then(|jwt_claims| { + set_cookie("user_id", &jwt_claims.user, &jwt_claims.exp) + .map(|_| jwt_claims.user.clone()) + .map_err(|e| anyhow!("Error clearing cookie: {}", e)) + }) + } else if status == 401 { + Err(anyhow!("Invalid username or password")) + } else { + Err(anyhow!("Could not authenticate: [{}]: {}", status, data)) + } + }); + FetchService::fetch_with_options(request, get_default_options(), handler) } pub fn logout(callback: Callback>) -> Result { let url = "/auth/logout"; - let handler = move |response: Response>| { - let (meta, maybe_data) = response.into_parts(); - let message = maybe_data - .map_err(|e| anyhow!("Could not reach authentication server: {}", e)) - .and_then(|data| { - if meta.status.is_success() { - Ok(()) - } else { - Err(anyhow!("Could not logout: [{}]: {}", meta.status, data)) - } - }); - callback.emit(message) - }; let request = Request::post(url).body(yew::format::Nothing)?; - FetchService::fetch_with_options(request, get_default_options(), handler.into()) + let handler = create_handler(callback, |status, data: String| { + if status.is_success() { + Ok(()) + } else { + Err(anyhow!("Could not logout: [{}]: {}", status, data)) + } + }); + FetchService::fetch_with_options(request, get_default_options(), handler) } }