problem set generator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

structs for questions and themes and parsing of questions from text files

+146 -25
+26
Cargo.lock
··· 349 349 ] 350 350 351 351 [[package]] 352 + name = "heck" 353 + version = "0.5.0" 354 + source = "registry+https://github.com/rust-lang/crates.io-index" 355 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 356 + 357 + [[package]] 352 358 name = "http" 353 359 version = "1.4.0" 354 360 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 648 654 "axum", 649 655 "genpdf", 650 656 "hyphenation", 657 + "strum", 658 + "strum_macros", 651 659 "tokio", 652 660 ] 653 661 ··· 909 917 version = "0.1.5" 910 918 source = "registry+https://github.com/rust-lang/crates.io-index" 911 919 checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" 920 + 921 + [[package]] 922 + name = "strum" 923 + version = "0.28.0" 924 + source = "registry+https://github.com/rust-lang/crates.io-index" 925 + checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" 926 + 927 + [[package]] 928 + name = "strum_macros" 929 + version = "0.28.0" 930 + source = "registry+https://github.com/rust-lang/crates.io-index" 931 + checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" 932 + dependencies = [ 933 + "heck", 934 + "proc-macro2", 935 + "quote", 936 + "syn 2.0.117", 937 + ] 912 938 913 939 [[package]] 914 940 name = "syn"
+2
Cargo.toml
··· 7 7 axum = "0.8.9" 8 8 genpdf = { version = "0.2.0", features = ["hyphenation"] } 9 9 hyphenation = { version = "0.8.4", features = ["embed_en-us"] } 10 + strum = "0.28.0" 11 + strum_macros = "0.28.0" 10 12 tokio = { version = "1.52.1", features = ["rt-multi-thread"] }
+24 -25
src/main.rs
··· 1 - use genpdf::{elements::{self, Paragraph}, fonts::FontData, style}; 1 + 2 + use std::str::FromStr; 3 + 4 + use genpdf::fonts::FontData; 2 5 use hyphenation::{Load, Standard}; 3 6 7 + mod util; 8 + use crate::util::{Question, build_document_base, build_response}; 4 9 5 10 use axum::{Router, extract::{Path, State}, http::{HeaderMap, header}, response::IntoResponse, routing::get}; 6 11 ··· 22 27 None => 1, 23 28 }; 24 29 25 - // this block should be really moved somewhere in a function 26 - let mut doc = genpdf::Document::new(state.font_family); 27 - doc.set_title("Test document title"); 28 - let mut decorator = genpdf::SimplePageDecorator::new(); 29 - decorator.set_margins(10); 30 - doc.set_page_decorator(decorator); 31 - let mut title = Paragraph::default(); 32 - title.push_styled("title", style::Effect::Bold); 33 - title.set_alignment(genpdf::Alignment::Center); 34 - doc.push(title); 35 - 36 - 37 - 38 - doc.push(elements::Break::new(5)); 39 - doc.set_hyphenator(state.hyphenator); 30 + let mut doc = build_document_base(state); 40 31 41 32 for i in 0..len { 42 33 doc.push( 43 34 genpdf::elements::Paragraph::new( 44 35 format!("this is line {}", i) 45 36 )); 46 - 47 - 48 37 } 49 38 50 - let mut headers = HeaderMap::new(); 51 - headers.insert(header::CONTENT_TYPE, "application/pdf".parse().unwrap()); 52 - 53 - 54 39 55 - let mut w: Vec<u8> = vec![]; 56 - let _ = doc.render(&mut w).expect("error during pdf rendering"); 57 - (headers,w.clone()) 40 + build_response(doc) 58 41 } 59 42 60 43 ··· 84 67 85 68 86 69 } 70 + 71 + 72 + 73 + 74 + #[test] 75 + fn test_string_to_question_parse() { 76 + let test_question = Question {subject:util::Subject::Math,theme:util::Theme::Math(util::MathTheme::ParametricEquations),text: "\n\n{{}} + y = 12".to_string()}; 77 + let test_string: &str = "Math 78 + ParametricEquations 79 + 80 + 81 + {{}} + y = 12"; 82 + 83 + assert_eq!(Question::from_str(test_string).unwrap(),test_question); 84 + 85 + }
+94
src/util.rs
··· 1 + 2 + use std::str::FromStr; 3 + 4 + use axum::{http::{HeaderMap, header}, response::IntoResponse}; 5 + use genpdf::{Document, elements::{self, Paragraph}, style}; 6 + use crate::GenpdfState; 7 + use strum_macros::{Display, EnumString}; 8 + 9 + 10 + #[derive(Debug,EnumString,Display,PartialEq)] 11 + pub enum Subject { 12 + Math, 13 + Physics 14 + } 15 + 16 + #[derive(Debug,Display,PartialEq)] 17 + pub enum Theme { 18 + Math(MathTheme), 19 + Physics(PhysTheme) 20 + } 21 + 22 + 23 + #[derive(Debug,EnumString,Display,PartialEq)] 24 + pub enum PhysTheme { 25 + LawMotion, 26 + Momentum, 27 + Energy, 28 + } 29 + 30 + #[derive(Debug,EnumString,Display,PartialEq)] 31 + pub enum MathTheme { 32 + ParametricEquations, 33 + InfiniteSequenceSeries, 34 + PartialDerivatives, 35 + 36 + } 37 + 38 + #[derive(Debug,PartialEq)] 39 + pub struct Question { 40 + pub subject: Subject, 41 + pub theme: Theme, 42 + pub text: String 43 + } 44 + 45 + #[derive(Debug,Display)] 46 + pub enum QuestionParseError { 47 + QuestionFileParseError, 48 + Strum(strum::ParseError) 49 + } 50 + 51 + impl FromStr for Question { 52 + type Err = QuestionParseError; 53 + fn from_str(s: &str) -> Result<Self, Self::Err> { 54 + let l : Vec<&str> = s.splitn(3, '\n').collect(); 55 + let subj: Subject = Subject::from_str(l[0]).unwrap(); 56 + let theme: Theme = match subj { 57 + Subject::Math => Theme::Math(MathTheme::from_str(l[1]).unwrap()), 58 + Subject::Physics => Theme::Physics(PhysTheme::from_str(l[1]).unwrap()), 59 + }; 60 + if !l[2].is_empty() { 61 + Ok(Question { subject: subj, theme: theme, text: l[2].to_string() }) 62 + } else { 63 + Err(QuestionParseError::QuestionFileParseError) 64 + } 65 + } 66 + 67 + } 68 + 69 + 70 + pub fn build_document_base(state:GenpdfState) -> Document { 71 + 72 + let mut doc = genpdf::Document::new(state.font_family); 73 + doc.set_title("Test document title"); 74 + let mut decorator = genpdf::SimplePageDecorator::new(); 75 + decorator.set_margins(10); 76 + doc.set_page_decorator(decorator); 77 + doc.set_hyphenator(state.hyphenator); 78 + let mut title = Paragraph::default(); 79 + title.push_styled("title", style::Effect::Bold); 80 + title.set_alignment(genpdf::Alignment::Center); 81 + doc.push(title); 82 + 83 + doc.push(elements::Break::new(5)); 84 + doc 85 + } 86 + 87 + pub fn build_response(doc: Document) -> impl IntoResponse { 88 + 89 + let mut headers = HeaderMap::new(); 90 + headers.insert(header::CONTENT_TYPE, "application/pdf".parse().unwrap()); 91 + let mut w: Vec<u8> = vec![]; 92 + let _ = doc.render(&mut w).expect("error during pdf rendering"); 93 + (headers,w) 94 + }