Skip to content

Commit

Permalink
Moves challenge info fetch into the helper
Browse files Browse the repository at this point in the history
  • Loading branch information
bitbrain-za committed Nov 11, 2023
1 parent 2e876fb commit 29ac79a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 51 deletions.
47 changes: 21 additions & 26 deletions src/code_editor/editor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::helpers::{
fetchers::{GetStatus, Getter},
refresh,
submission::{Submission, SubmissionPromise, SubmissionResult},
Challenges, Languages,
Expand Down Expand Up @@ -37,8 +38,9 @@ pub struct CodeEditor {
active_challenge: Challenges,
#[serde(skip)]
selected_challenge: Challenges,

#[serde(skip)]
info_promise: Option<Promise<Result<String, String>>>,
info_fetcher: Option<Getter<String>>,
}

impl Default for CodeEditor {
Expand All @@ -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(),
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/helpers/challenges.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use super::fetchers::{GetStatus, Getter};

Check warning on line 1 in src/helpers/challenges.rs

View workflow job for this annotation

GitHub Actions / Check

unused import: `GetStatus`

Check failure on line 1 in src/helpers/challenges.rs

View workflow job for this annotation

GitHub Actions / Clippy

unused import: `GetStatus`

Check warning on line 1 in src/helpers/challenges.rs

View workflow job for this annotation

GitHub Actions / Check wasm32

unused import: `GetStatus`

Check warning on line 1 in src/helpers/challenges.rs

View workflow job for this annotation

GitHub Actions / Test Suite

unused import: `GetStatus`
use std::fmt::{self, Display, Formatter};

#[derive(
Expand Down Expand Up @@ -34,6 +35,18 @@ impl Challenges {
Challenges::None => "".to_string(),
}
}

pub fn fetcher(&self, context: Option<&egui::Context>) -> Option<Getter<String>> {
match self {
Challenges::None => None,
_ => {
let mut getter = Getter::<String>::new(&self.get_info_url(), context, false);
getter.get();

Some(getter)
}
}
}
}

impl Display for Challenges {
Expand Down
67 changes: 42 additions & 25 deletions src/helpers/fetchers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,22 @@ pub enum GetStatus<T: Clone + Sync + Send> {
}

pub struct Getter<T: Clone + Sync + Send + 'static> {

Check warning on line 14 in src/helpers/fetchers.rs

View workflow job for this annotation

GitHub Actions / Check

struct `Getter` is never constructed
pub promise: Option<Promise<Result<T, String>>>,
promise: Option<Promise<Result<T, String>>>,
with_credentials: bool,
context: Option<egui::Context>,
url: String,
}

impl<T: Clone + Sync + Send> Getter<T> {
pub fn new(url: &str, ctx: Option<&egui::Context>, with_credentials: bool) -> Self {

Check warning on line 22 in src/helpers/fetchers.rs

View workflow job for this annotation

GitHub Actions / Check

associated items `new` and `check_promise` are never used
Self {
url: url.to_string(),
promise: None,
with_credentials,
context: ctx.cloned(),
}
}

pub fn check_promise(&mut self) -> GetStatus<T> {
let mut res = GetStatus::<T>::NotStarted;
if let Some(promise) = &self.promise {
Expand All @@ -29,44 +41,49 @@ impl<T: Clone + Sync + Send> Getter<T> {
}
res
}
pub fn get(
&mut self,
url: &'static str,
ctx: Option<&'static egui::Context>,
) -> Promise<Result<String, String>> {
Promise::spawn_local(async move {
let response = http::Request::get(url)
.credentials(RequestCredentials::Include)
.send()
.await
.map_err(|e| e.to_string())?;
}

impl Getter<String> {
pub fn get(&mut self) {

Check warning on line 47 in src/helpers/fetchers.rs

View workflow job for this annotation

GitHub Actions / Check

method `get` is never used
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
}
match response.text().await {
Ok(text) => Ok(text),
Err(e) => Err(e.to_string()),
}
})
});
self.promise = Some(promise);
}
}

impl<T: Clone + DeserializeOwned + Sync + Send> Getter<T> {
pub fn get_json(
&mut self,
url: &'static str,
ctx: Option<&'static egui::Context>,
) -> Promise<Result<T, String>> {
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) {

Check warning on line 71 in src/helpers/fetchers.rs

View workflow job for this annotation

GitHub Actions / Check

method `get_json` is never used
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::<T>().await.map_err(|e| e.to_string())
})
});
self.promise = Some(promise);
}
}

0 comments on commit 29ac79a

Please sign in to comment.