From 29ac79a59519f6cae82b6f2d3133c26442cfa5d4 Mon Sep 17 00:00:00 2001 From: phil Date: Sat, 11 Nov 2023 12:52:22 +0200 Subject: [PATCH] Moves challenge info fetch into the helper --- src/code_editor/editor.rs | 47 ++++++++++++--------------- src/helpers/challenges.rs | 13 ++++++++ src/helpers/fetchers.rs | 67 ++++++++++++++++++++++++--------------- 3 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/code_editor/editor.rs b/src/code_editor/editor.rs index 7d8a2ec..80e8c7d 100644 --- a/src/code_editor/editor.rs +++ b/src/code_editor/editor.rs @@ -1,4 +1,5 @@ use crate::helpers::{ + fetchers::{GetStatus, Getter}, refresh, submission::{Submission, SubmissionPromise, SubmissionResult}, Challenges, Languages, @@ -37,8 +38,9 @@ pub struct CodeEditor { active_challenge: Challenges, #[serde(skip)] selected_challenge: Challenges, + #[serde(skip)] - info_promise: Option>>, + info_fetcher: Option>, } impl Default for CodeEditor { @@ -59,7 +61,7 @@ impl Default for CodeEditor { last_result: SubmissionResult::NotStarted, toasts: Toasts::default(), token_refresh_promise: None, - info_promise: None, + info_fetcher: None, active_challenge: Challenges::None, selected_challenge: Challenges::default(), } @@ -110,39 +112,32 @@ impl CodeEditor { self.promise = Some(promise); } + fn fetch(&mut self, ctx: &egui::Context) { if self.active_challenge == self.selected_challenge { return; } + log::debug!("Fetching challenge info"); self.active_challenge = self.selected_challenge; - - let url = self.selected_challenge.get_info_url(); - let ctx = ctx.clone(); - - let promise = poll_promise::Promise::spawn_local(async move { - let response = http::Request::get(&url); - let response = response.send().await.unwrap(); - let text = response.text().await.map_err(|e| format!("{:?}", e)); - ctx.request_repaint(); // wake up UI thread - text - }); - self.info_promise = Some(promise); + self.info_fetcher = self.selected_challenge.fetcher(Some(ctx)); } fn check_info_promise(&mut self) { - if let Some(promise) = &self.info_promise { - if let Some(result) = promise.ready() { - match result { - Ok(text) => { - self.instructions = text.into(); - } - Err(err) => { - self.toasts - .error(format!("Error fetching challenge info: {}", err)) - .set_duration(Some(Duration::from_secs(5))); + let getter = &mut self.info_fetcher; + + if let Some(getter) = getter { + match &getter.check_promise() { + GetStatus::NotStarted => {} + GetStatus::InProgress => {} + GetStatus::Success(text) => { + self.instructions = text.clone(); + } + GetStatus::Failed(err) => { + self.toasts + .error(format!("Error fetching challenge info: {}", err)) + .set_duration(Some(Duration::from_secs(5))); - log::error!("Error fetching file: {}", err); - } + log::error!("Error fetching file: {}", err); } } } diff --git a/src/helpers/challenges.rs b/src/helpers/challenges.rs index d16b2fe..ae45933 100644 --- a/src/helpers/challenges.rs +++ b/src/helpers/challenges.rs @@ -1,3 +1,4 @@ +use super::fetchers::{GetStatus, Getter}; use std::fmt::{self, Display, Formatter}; #[derive( @@ -34,6 +35,18 @@ impl Challenges { Challenges::None => "".to_string(), } } + + pub fn fetcher(&self, context: Option<&egui::Context>) -> Option> { + match self { + Challenges::None => None, + _ => { + let mut getter = Getter::::new(&self.get_info_url(), context, false); + getter.get(); + + Some(getter) + } + } + } } impl Display for Challenges { diff --git a/src/helpers/fetchers.rs b/src/helpers/fetchers.rs index 73ee0b7..2058a6b 100644 --- a/src/helpers/fetchers.rs +++ b/src/helpers/fetchers.rs @@ -12,10 +12,22 @@ pub enum GetStatus { } pub struct Getter { - pub promise: Option>>, + promise: Option>>, + with_credentials: bool, + context: Option, + url: String, } impl Getter { + pub fn new(url: &str, ctx: Option<&egui::Context>, with_credentials: bool) -> Self { + Self { + url: url.to_string(), + promise: None, + with_credentials, + context: ctx.cloned(), + } + } + pub fn check_promise(&mut self) -> GetStatus { let mut res = GetStatus::::NotStarted; if let Some(promise) = &self.promise { @@ -29,17 +41,20 @@ impl Getter { } res } - pub fn get( - &mut self, - url: &'static str, - ctx: Option<&'static egui::Context>, - ) -> Promise> { - Promise::spawn_local(async move { - let response = http::Request::get(url) - .credentials(RequestCredentials::Include) - .send() - .await - .map_err(|e| e.to_string())?; +} + +impl Getter { + pub fn get(&mut self) { + let url = self.url.clone(); + let ctx = self.context.clone(); + let with_credentials = self.with_credentials; + let promise = Promise::spawn_local(async move { + let request = http::Request::get(&url); + let request = match with_credentials { + true => request.credentials(RequestCredentials::Include), + false => request, + }; + let response = request.send().await.map_err(|e| e.to_string())?; if let Some(ctx) = ctx { ctx.request_repaint(); // wake up UI thread } @@ -47,26 +62,28 @@ impl Getter { Ok(text) => Ok(text), Err(e) => Err(e.to_string()), } - }) + }); + self.promise = Some(promise); } } impl Getter { - pub fn get_json( - &mut self, - url: &'static str, - ctx: Option<&'static egui::Context>, - ) -> Promise> { - Promise::spawn_local(async move { - let response = http::Request::get(url) - .credentials(RequestCredentials::Include) - .send() - .await - .map_err(|e| e.to_string())?; + pub fn get_json(&mut self) { + let url = self.url.clone(); + let ctx = self.context.clone(); + let with_credentials = self.with_credentials; + let promise = Promise::spawn_local(async move { + let request = http::Request::get(&url); + let request = match with_credentials { + true => request.credentials(RequestCredentials::Include), + false => request, + }; + let response = request.send().await.map_err(|e| e.to_string())?; if let Some(ctx) = ctx { ctx.request_repaint(); // wake up UI thread } response.json::().await.map_err(|e| e.to_string()) - }) + }); + self.promise = Some(promise); } }