11use crate :: handlers:: leetcode:: * ;
22
3+ use eyre:: { bail, Context , Result } ;
4+
35impl LeetCode < Authorized > {
4- pub fn get_daily_challenge ( & self ) -> Result < DailyChallenge , & str > {
6+ pub fn get_daily_challenge ( & self ) -> Result < DailyChallenge > {
57 let url = "https://leetcode.com/graphql" ;
68 let client = & self . client ;
79 let query = GraphqlRequest {
810 query : "\n query questionOfToday {\n activeDailyCodingChallengeQuestion {\n date\n userStatus\n link\n question {\n acRate\n difficulty\n freqBar\n frontendQuestionId: questionFrontendId\n isFavor\n paidOnly: isPaidOnly\n status\n title\n titleSlug\n hasVideoSolution\n hasSolution\n topicTags {\n name\n id\n slug\n }\n }\n }\n }\n " . to_string ( ) ,
911 variables : "{}" . to_string ( ) ,
1012 } ;
11- let Ok ( data ) = client . post ( url ) . json ( & query ) . send ( ) else {
12- return Err ( "Failed to fetch daily challenge from leetcode!" ) ;
13- } ;
13+
14+ let data = client . post ( url ) . json ( & query ) . send ( ) ? ;
15+
1416 // println!("{:?}", data.text());
1517 // todo!();
18+
1619 #[ derive( Deserialize ) ]
1720 #[ allow( non_snake_case) ]
1821 struct DailyChallengeWrapper {
@@ -22,43 +25,38 @@ impl LeetCode<Authorized> {
2225 struct Wrapper {
2326 data : DailyChallengeWrapper ,
2427 }
28+
2529 Ok ( data
26- . json :: < Wrapper > ( )
27- . map_err ( |_| "Failed to parse daily challenge!" ) ?
30+ . json :: < Wrapper > ( ) ?
2831 . data
2932 . activeDailyCodingChallengeQuestion )
3033 }
3134
32- pub fn get_metadata ( & self ) -> Result < UserMetadata , & str > {
35+ pub fn get_metadata ( & self ) -> Result < UserMetadata > {
3336 let client = & self . client ;
34- let Ok ( data) = client
37+ let data = client
3538 . get ( "https://leetcode.com/api/problems/all/" )
36- . send ( ) else {
37- return Err ( "Failed to fetch metadata from leetcode!" ) ;
38- } ;
39+ . send ( )
40+ . wrap_err ( "Failed to fetch metadata from LeetCode" ) ?;
3941
4042 let metadata = data
4143 . json :: < UserMetadata > ( )
42- . map_err ( |_| "Failed to parse metadata! Try renewing cookie" ) ;
43- if let Ok ( metadata) = metadata. as_ref ( ) {
44- if metadata. user_name == "" {
45- return Err ( "Cookie invalid. Renew cookies" ) ;
46- }
44+ . wrap_err ( "Failed to parse metadata, Try renewing cookie" ) ?;
45+ if metadata. user_name . is_empty ( ) {
46+ bail ! ( "Cookie invalid. Renew cookies" ) ;
4747 }
48- metadata
48+ Ok ( metadata)
4949 }
5050
51- pub fn question_content ( & self , title_slug : & str ) -> Result < LeetcodeQuestion , & str > {
51+ pub fn question_content ( & self , title_slug : & str ) -> Result < LeetcodeQuestion > {
5252 let client = & self . client ;
5353 let url = "https://leetcode.com/graphql" ;
5454 let query = GraphqlRequest {
5555 query : "query questionContent($titleSlug: String!) { question(titleSlug: $titleSlug) { content mysqlSchemas }}" . to_string ( ) ,
5656 variables : serde_json:: to_string ( & Variables { titleSlug : title_slug. to_string ( ) } ) . unwrap ( ) ,
5757 } ;
5858
59- let Ok ( data) = client. post ( url) . json ( & query) . send ( ) else {
60- return Err ( "Failed to fetch question id from leetcode!" ) ;
61- } ;
59+ let data = client. post ( url) . json ( & query) . send ( ) ?;
6260
6361 #[ derive( Deserialize ) ]
6462 struct QuestionWrapper {
@@ -72,18 +70,14 @@ impl LeetCode<Authorized> {
7270 let query = "\n query questionEditorData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n codeSnippets {\n lang\n langSlug\n code\n }\n envInfo\n enableRunCode\n }\n }\n " ;
7371 let varibales = serde_json:: to_string ( & Variables {
7472 titleSlug : title_slug. to_string ( ) ,
75- } )
76- . unwrap ( ) ;
77- let Ok ( boiler_code) = client
73+ } ) ?;
74+ let boiler_code = client
7875 . post ( url)
7976 . json ( & GraphqlRequest {
8077 query : query. to_string ( ) ,
8178 variables : varibales,
8279 } )
83- . send ( )
84- else {
85- return Err ( "Failed to fetch boiler plate code!" ) ;
86- } ;
80+ . send ( ) ?;
8781
8882 #[ derive( Debug , Deserialize ) ]
8983 #[ allow( non_snake_case) ]
@@ -99,51 +93,37 @@ impl LeetCode<Authorized> {
9993 data : WrapperData ,
10094 }
10195
102- let boiler_code_vector = boiler_code
103- . json :: < Wrapper > ( )
104- . map_err ( |_| "Failed to parse boiler plate code!" ) ?
105- . data
106- . question
107- . codeSnippets ;
96+ let boiler_code_vector = boiler_code. json :: < Wrapper > ( ) ?. data . question . codeSnippets ;
10897
109- let boiler_code_vector = boiler_code_vector
98+ let mut boiler_code_vector = boiler_code_vector
11099 . into_iter ( )
111100 . filter ( |code| code. is_supported ( ) )
112101 . collect :: < Vec < _ > > ( ) ;
113102
114103 // ask user to specify language among these options without using external lib
115- let boiler_code = if boiler_code_vector. len ( ) == 1 {
116- boiler_code_vector. into_iter ( ) . next ( ) . unwrap ( )
117- } else if !boiler_code_vector. is_empty ( ) {
118- let mut input = String :: new ( ) ;
119- println ! ( "\n Please select a language from the following options :" ) ;
120- for ( i, code) in boiler_code_vector. iter ( ) . enumerate ( ) {
121- println ! ( "{}: {}" , i, code. langSlug) ;
122- }
123- println ! (
124- "\n For example : Input \" {}\" for {}" ,
125- 0 , & boiler_code_vector[ 0 ] . langSlug
126- ) ;
127- if let Err ( _) = std:: io:: stdin ( ) . read_line ( & mut input) {
128- return Err ( "Failed to read input!" ) ;
104+ let boiler_code = match boiler_code_vector. len ( ) {
105+ 0 => bail ! ( "No boiler plate code available in supported language!" ) ,
106+ 1 => boiler_code_vector. swap_remove ( 0 ) ,
107+ _ => {
108+ let mut input = String :: new ( ) ;
109+ println ! ( "\n Please select a language from the following options :" ) ;
110+ for ( i, code) in boiler_code_vector. iter ( ) . enumerate ( ) {
111+ println ! ( "{}: {}" , i, code. langSlug) ;
112+ }
113+ println ! (
114+ "\n For example : Input \" {}\" for {}" ,
115+ 0 , & boiler_code_vector[ 0 ] . langSlug
116+ ) ;
117+ std:: io:: stdin ( ) . read_line ( & mut input) ?;
118+ let input = input. trim ( ) ;
119+ let input = input. parse :: < usize > ( ) ?;
120+ boiler_code_vector. swap_remove ( input)
129121 }
130- let input = input. trim ( ) ;
131- let Ok ( input) = input. parse :: < usize > ( ) else {
132- return Err ( "Invalid input!" ) ;
133- } ;
134- if let Some ( code) = boiler_code_vector. into_iter ( ) . nth ( input) {
135- code
136- } else {
137- return Err ( "Invalid input!" ) ;
138- }
139- } else {
140- return Err ( "No boiler plate code available in supported language!" ) ;
141122 } ;
123+
142124 let mut input = String :: new ( ) ;
143125 println ! ( "Filename (main.{}) : " , & ( boiler_code. extension( ) ) ) ;
144- if let Err ( _) = std:: io:: stdin ( ) . read_line ( & mut input) {
145- return Err ( "Failed to read input!" ) ;
146- }
126+ std:: io:: stdin ( ) . read_line ( & mut input) ?;
147127 let input = input. trim ( ) ;
148128 let filename = if input. is_empty ( ) {
149129 format ! ( "main.{}" , boiler_code. extension( ) )
@@ -152,9 +132,7 @@ impl LeetCode<Authorized> {
152132 } ;
153133 boiler_code. save_code ( & filename, & title_slug) ;
154134
155- data. json :: < Data > ( )
156- . map_err ( |_| "Failed to parse question content!" )
157- . map ( |op| op. data . question )
135+ Ok ( data. json :: < Data > ( ) . map ( |op| op. data . question ) ?)
158136 }
159137
160138 pub fn question_metadata ( & self , title_slug : & str ) -> Result < Question , & str > {
0 commit comments