Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change code editor to use new methods #14

Merged
merged 1 commit into from
Dec 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "challenge_frontend"
version = "2.2.1"
version = "2.2.2"
edition = "2021"
rust-version = "1.71"
authors = ["Philip Barlow"]
Expand Down
23 changes: 20 additions & 3 deletions src/apps/challenge_info.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::helpers::{fetchers::Requestor, AppState, Challenges};
use crate::helpers::{
fetchers::{RequestStatus, Requestor},
AppState, ChallengeCollection, Challenges,
};
use egui_commonmark::*;
use std::borrow::BorrowMut;
use std::sync::{Arc, Mutex};
Expand All @@ -20,6 +23,8 @@ pub struct ChallengeInfoApp {
instructions: String,
#[serde(skip)]
app_state: Arc<Mutex<AppState>>,
#[serde(skip)]
challenges: ChallengeCollection,
}

impl Default for ChallengeInfoApp {
Expand All @@ -30,6 +35,7 @@ impl Default for ChallengeInfoApp {
active_challenge: Challenges::None,
instructions: "None".to_string(),
app_state: Arc::new(Mutex::new(AppState::default())),
challenges: ChallengeCollection::default(),
}
}
}
Expand All @@ -42,14 +48,25 @@ impl ChallengeInfoApp {
log::debug!("Fetching challenge info");
self.active_challenge = self.selected_challenge;
let app_state = Arc::clone(&self.app_state);
self.info_fetcher = self.selected_challenge.fetcher(app_state);
self.info_fetcher = self.challenges.fetch(app_state);
}
fn check_info_promise(&mut self) {
let getter = &mut self.info_fetcher;

if let Some(getter) = getter {
let result = &getter.check_promise();
self.instructions = result.to_string();
match result {
RequestStatus::NotStarted => {}
RequestStatus::InProgress => {}
RequestStatus::Success(_) => {
self.info_fetcher = None;
}
RequestStatus::Failed(_) => {
self.info_fetcher = None;
}
}
self.challenges = ChallengeCollection::from_json(&result.to_string());
self.instructions = self.challenges.get_instructions(self.selected_challenge);
}
}
}
Expand Down
19 changes: 13 additions & 6 deletions src/code_editor/editor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::helpers::{
fetchers::{RequestStatus, Requestor},
submission::{Submission, SubmissionResult},
AppState, Challenges, Languages,
AppState, ChallengeCollection, Challenges, Languages,
};
use egui::*;
use egui_commonmark::*;
Expand Down Expand Up @@ -36,6 +36,8 @@ pub struct CodeEditor {
submitter: Option<Requestor>,
#[serde(skip)]
pub app_state: Arc<Mutex<AppState>>,
#[serde(skip)]
challenges: ChallengeCollection,
}

impl Default for CodeEditor {
Expand All @@ -58,6 +60,7 @@ impl Default for CodeEditor {
active_challenge: Challenges::None,
selected_challenge: Challenges::default(),
app_state: Arc::new(Mutex::new(AppState::default())),
challenges: ChallengeCollection::default(),
}
}
}
Expand All @@ -77,7 +80,7 @@ impl CodeEditor {
log::debug!("Fetching challenge info");
self.active_challenge = self.selected_challenge;
let app_state = Arc::clone(&self.app_state);
self.info_fetcher = self.selected_challenge.fetcher(app_state);
self.info_fetcher = self.challenges.fetch(app_state);
}

fn check_info_promise(&mut self) {
Expand All @@ -86,17 +89,21 @@ impl CodeEditor {
if let Some(getter) = getter {
let result = &getter.check_promise();
match result {
RequestStatus::NotStarted => {}
RequestStatus::InProgress => {}
RequestStatus::Success(_) => {
self.info_fetcher = None;
}
RequestStatus::Failed(err) => {
self.toasts
.error(format!("Error fetching challenge info: {}", err))
.set_duration(Some(Duration::from_secs(5)));

log::error!("Error fetching document: {}", err);
}
_ => {
self.instructions = result.to_string();
self.info_fetcher = None;
}
}
self.challenges = ChallengeCollection::from_json(&result.to_string());
self.instructions = self.challenges.get_instructions(self.selected_challenge);
}
}
}
Expand Down
128 changes: 107 additions & 21 deletions src/helpers/challenges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,35 +27,121 @@ impl Challenges {
Challenges::None => Challenges::None,
}
}
}

pub fn get_info_url(&self) -> String {
impl Display for Challenges {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Challenges::C2331 => "https://raw.githubusercontent.com/bitbrain-za/judge_2331-rs/main/src/generator/2331.md".to_string(),
Challenges::C2332 => "https://raw.githubusercontent.com/bitbrain-za/judge_2331-rs/main/src/generator/2332.md".to_string(),
Challenges::C2333 => "https://raw.githubusercontent.com/bitbrain-za/judge_2331-rs/main/src/generator/2333.md".to_string(),
Challenges::None => "".to_string(),
Challenges::C2331 => write!(f, "2331"),
Challenges::C2332 => write!(f, "2332"),
Challenges::C2333 => write!(f, "2333"),
Challenges::None => write!(f, "None"),
}
}
}

pub fn fetcher(&self, app_state: Arc<Mutex<AppState>>) -> Option<Requestor> {
match self {
Challenges::None => None,
_ => {
let mut getter = Requestor::new_get(app_state, &self.get_info_url(), false);
getter.send();
Some(getter)
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Challenge {
pub name: String,
pub command: String,
pub table: String,
doc: String,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ChallengeCollection {
pub items: Vec<Challenge>,
url: String,
}

impl Default for ChallengeCollection {
fn default() -> Self {
Self::new()
}
}

impl Display for Challenges {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Challenges::C2331 => write!(f, "23_3_1"),
Challenges::C2332 => write!(f, "23_3_2"),
Challenges::C2333 => write!(f, "23_3_3"),
Challenges::None => write!(f, "None"),
impl ChallengeCollection {
pub fn new() -> Self {
let url = option_env!("BACKEND_URL")
.unwrap_or("http://123.4.5.6:3000/")
.to_string();

Self {
items: Vec::new(),
url,
}
}

pub fn fetch(&mut self, app_state: Arc<Mutex<AppState>>) -> Option<Requestor> {
let url = format!("{}api/game/challenge", self.url);

log::debug!("Fetching challenge info");
let app_state = Arc::clone(&app_state.clone());
let mut getter = Requestor::new_get(app_state, &url, true);
getter.send();
Some(getter)
}

pub fn from_json(json: &str) -> Self {
let items: Vec<Challenge> = serde_json::from_str(json).unwrap_or_default();
log::debug!("Found {} challenges", items.len());
Self {
items,
..Default::default()
}
}

pub fn get_instructions(&self, challenge: Challenges) -> String {
log::debug!("Getting instructions for {}", challenge);
match self
.items
.iter()
.find(|c| c.command == challenge.to_string())
{
Some(c) => c.doc.clone(),
None => String::from("No instructions found"),
}
}
}

#[cfg(test)]
mod tests {
use serde_json::Value;

use super::*;

#[test]
fn test_parse_json() {
let output = r#"[
{
"command": "2331",
"doc": " # Find Odds\n\n## Problem\n\nGiven an array of integers, find the one that appears an odd number of times.\n\nThere will always be only one integer that appears an odd number of times.\n\nExamples:\n\n- [7] should return 7, because it occurs 1 time (which is odd).\n- [0] should return 0, because it occurs 1 time (which is odd).\n- [1,1,2] should return 2, because it occurs 1 time (which is odd).\n- [0,1,0,1,0] should return 0, because it occurs 3 times (which is odd).\n- [1,2,2,3,3,3,4,3,3,3,2,2,1] should return 4, because it appears 1 time (which is odd).\n\n## Instructions\n\nDesign a program/script that can solve this problem in a fast/interesting/elegant way.\nYour program should be able to accept a single command line argument for a filename.\n\nThis file will be a json formatted array of arrays of numbers ranging from 0-255.\n\nReturn your results as a single array.\nFor example If you ran a file with the 5 examples above the output would look like: [7,0,2,3,4]\n\n## Testing:\n\nThere is a JSON sample file containing 500 arrays for you to view and test against.\nThere is a script called \"check.sh\" which you can use to check against the sample data.\n\nTo use the script, call it with the command to run your program as an argument\n\n```bash\n./check.sh \"./my_program\"\n```\n\n## Making an attempt\n\nFor a real run, you will be tested against 100 000 random samples.\n\n```bash\njudge -C 2331 -n Player1 -c \"python my_code.py\" -L python\njudge -C 2331 -n Player2 -c \"./my_binary\" -L go\n```\n\n",
"name": "Find the odd one out",
"table": "23_3_1"
},
{
"command": "2332",
"doc": " # Find Odd One Out Two\n\n## Problem\n\nGiven an array of integers, find the one that appears an odd number of times.\n\nThere will always be only one integer that appears an odd number of times.\n\nExamples:\n\n- [7] should return 7, because it occurs 1 time (which is odd).\n- [0] should return 0, because it occurs 1 time (which is odd).\n- [1,1,2] should return 2, because it occurs 1 time (which is odd).\n- [0,1,0,1,0] should return 0, because it occurs 3 times (which is odd).\n- [1,2,2,3,3,3,4,3,3,3,2,2,1] should return 4, because it appears 1 time (which is odd).\n\n## Instructions\n\nIf the arguments are empty, print a \"0\" and return.\n\nDesign a program/script that can solve this problem in a fast/interesting/elegant way.\n\nYour program will need to run in a loop, listing to stdin.\nAn array will be given in the form \"5,7,2,7,2,3,5\\n\" and you will output \"3\\n\".\n\nNB: inputs and outputs must all be terminated with a newline!\nIf your program receives a \"q\\n\" as an input, it must exit gracefully and quietly.\n\n## Making an attempt\n\nFor a real run, you will be tested against 10 000 random samples.\n\n```bash\njudge -C 2332 -c \"python my_code.py\" -L python\njudge -C 2332 -c \"./my_binary\" -L go\n```\n\n",
"name": "Find the odd one out two",
"table": "23_3_2"
},
{
"command": "2333",
"doc": " # How Big?!\n\n## Problem\n\nGiven an array of integers, find the magnitude.\nReturn your result as an unsigned integer (discard the non-integer components)\n\nExamples:\n\n- [7] should return 7\n- [0] should return 0\n- [1,1,2] should return 2\n- [1,2,3,4] should return 5\n- [5,5,5,5] should return 10\n\n## Instructions\n\nIf the arguments are empty, print a \"0\" and return.\n\nDesign a program/script that can solve this problem in a fast/interesting/elegant way.\n\nYour program will need to run in a loop, listing to stdin.\nAn array will be given in the form \"5,7,2,7,2,3,5\\n\" and you will output \"13\\n\".\n\nNB: inputs and outputs must all be terminated with a newline!\nIf your program receives a \"q\\n\" as an input, it must exit gracefully and quietly.\n\n## Making an attempt\n\nFor a real run, you will be tested against 10 000 random samples.\n\n```bash\njudge -C 2333 -c \"python my_code.py\" -L python\njudge -C 2333 \"./my_binary\" -L go\n```\n\n",
"name": "How big?",
"table": "23_3_3"
},
{
"command": "2334",
"doc": " # Find the bad character\n\n## Problem\n\nGiven a string, find the non alphanumeric character. Anything outside of the A-Z, a-z and 0-9 range\nReturn the bad character. If more than one bad character are in the string, just return the first one.\n\nExamples:\n\n- \"Hello,world\" should return ,\n- \"This|isbad\" should return |\n- \"123456=89\" should return =\n\n## Instructions\n\nDesign a program/script that can solve this problem in a fast/interesting/elegant way.\n\nYour program will need to run in a loop, listing to stdin.\nA string will be given in the form \"sting_to_be_inspected\\n\" and you will output \"_\\n\".\n\nNB: inputs and outputs must all be terminated with a newline!\nIf your program receives a \"\\n\" as an input, it must exit gracefully and quietly.\n\n## Making an attempt\n\nFor a real run, you will be tested against X random samples.\n\n```bash\njudge -C 2333 -c \"python my_code.py\" -L python\njudge -C 2333 \"./my_binary\" -L go\n```\n\n\n",
"name": "Input validation",
"table": "23_3_4"
}
]"#;

let _: Value = serde_json::from_str(output).unwrap();
let challenges = ChallengeCollection::from_json(output);

assert_eq!(challenges.items[0].name, "Find the odd one out");
}
}
1 change: 1 addition & 0 deletions src/helpers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod challenges;
pub use challenges::ChallengeCollection;
pub use challenges::Challenges;
mod languages;
pub use languages::Languages;
Expand Down
Loading