1- use std:: {
2- self ,
3- cmp:: Ordering ,
4- fs:: File ,
5- io:: { self , ErrorKind } ,
6- path:: Path ,
7- process:: exit,
8- str,
9- sync:: { Arc , Mutex } ,
10- } ;
111use tiny_http:: { Header , Method , Request , Response , Server , StatusCode } ;
2+ use std:: {
3+ self ,
4+ cmp:: Ordering ,
5+ fs:: File ,
6+ io:: { self , ErrorKind } ,
7+ path:: Path ,
8+ process:: exit,
9+ str,
10+ sync:: { Arc , Mutex }
11+ } ;
1212
13- use super :: model:: * ;
1413use colored:: Colorize ;
14+ use super :: model:: * ;
1515
1616pub fn serve_404 ( request : Request ) -> io:: Result < ( ) > {
1717 return request. respond ( Response :: from_string ( "404" ) . with_status_code ( StatusCode ( 404 ) ) ) ;
1818}
1919
20+
2021pub fn serve_500 ( request : Request ) -> io:: Result < ( ) > {
2122 return request. respond ( Response :: from_string ( "500" ) . with_status_code ( StatusCode ( 500 ) ) ) ;
2223}
2324
25+
2426pub fn serve_400 ( request : Request , message : & str ) -> io:: Result < ( ) > {
25- return request. respond (
26- Response :: from_string ( format ! ( "400: {message}" ) ) . with_status_code ( StatusCode ( 400 ) ) ,
27- ) ;
27+ return request. respond ( Response :: from_string ( format ! ( "400: {message}" ) ) . with_status_code ( StatusCode ( 400 ) ) ) ;
2828}
2929
30+
3031pub fn serve_static_file ( request : Request , file_path : & str , content_type : & str ) -> io:: Result < ( ) > {
3132 let html_file = match File :: open ( Path :: new ( file_path) ) {
32- Ok ( file) => file,
33+ Ok ( file) => file,
3334 Err ( err) => {
34- eprintln ! (
35- "{}: Could not open html file {file_path} as {err}" ,
36- "ERROR" . bold( ) . red( ) ,
37- file_path = file_path. bright_blue( ) ,
38- err = err. to_string( ) . red( )
39- ) ;
35+ eprintln ! ( "{}: Could not open html file {file_path} as {err}" , "ERROR" . bold( ) . red( ) , file_path = file_path. bright_blue( ) , err = err. to_string( ) . red( ) ) ;
4036 if err. kind ( ) == ErrorKind :: NotFound {
4137 return serve_404 ( request) ;
4238 }
4339 return serve_500 ( request) ;
4440 }
4541 } ;
46- let header = Header :: from_bytes ( "Content-Type" , content_type)
47- . expect ( "Should be a valid Content-Type while passing the header." ) ;
42+ let header = Header :: from_bytes ( "Content-Type" , content_type) . expect ( "Should be a valid Content-Type while passing the header." ) ;
4843 return request. respond ( Response :: from_file ( html_file) . with_header ( header) ) ;
4944}
5045
51- pub fn serve_api_search ( mut request : Request , model : Arc < Mutex < InMemoryModel > > ) -> io:: Result < ( ) > {
46+
47+ pub fn serve_api_search ( mut request : Request , model : Arc < Mutex < InMemoryModel > > ) -> io:: Result < ( ) > {
5248 let mut buf = Vec :: new ( ) ;
53- // Read the entire body of request
49+ // Read the entire body of request
5450 if let Err ( err) = request. as_reader ( ) . read_to_end ( & mut buf) {
55- eprintln ! (
56- "{}: Could not read body of request as {err}" ,
57- "ERROR" . bold( ) . red( ) ,
58- err = err. to_string( ) . red( )
59- ) ;
51+ eprintln ! ( "{}: Could not read body of request as {err}" , "ERROR" . bold( ) . red( ) , err = err. to_string( ) . red( ) ) ;
6052 return serve_500 ( request) ;
6153 }
6254
6355 let body = match str:: from_utf8 ( & mut buf) {
64- Ok ( body) => body. chars ( ) . collect :: < Vec < _ > > ( ) ,
56+ Ok ( body) => body. chars ( ) . collect :: < Vec < _ > > ( ) ,
6557 Err ( err) => {
66- eprintln ! (
67- "{}: Could not interpret body as UTF-8 string as {err}" ,
68- "ERROR" . bold( ) . red( ) ,
69- err = err. to_string( ) . red( )
70- ) ;
58+ eprintln ! ( "{}: Could not interpret body as UTF-8 string as {err}" , "ERROR" . bold( ) . red( ) , err = err. to_string( ) . red( ) ) ;
7159 return serve_400 ( request, "Body must be a valid UTF-8 string" ) ;
7260 }
7361 } ;
7462
75- println ! (
76- "Recieved Query: \' {}\' " ,
77- body. iter( ) . collect:: <String >( ) . bright_blue( )
78- ) ;
63+ println ! ( "Recieved Query: \' {}\' " , body. iter( ) . collect:: <String >( ) . bright_blue( ) ) ;
7964
8065 let model = model. lock ( ) . unwrap ( ) ;
8166 let results = match model. search_query ( & body) {
82- Ok ( results) => results,
83- Err ( ( ) ) => return serve_500 ( request) ,
67+ Ok ( results) => results,
68+ Err ( ( ) ) => return serve_500 ( request)
8469 } ;
85-
86- let mut content = Vec :: new ( ) ;
70+
71+ let mut content= Vec :: new ( ) ;
8772 // Display document ranks (if rank turns 0 while iterating, stop from there)
8873 for ( path, rank) in results. iter ( ) . take ( 10 ) {
8974 if rank. partial_cmp ( & 0f32 ) == Some ( Ordering :: Equal ) {
9075 break ;
9176 }
9277 println ! ( " {} => {}" , path. display( ) , rank) ;
9378 content. push ( ( path, rank) ) ;
94- }
79+ }
9580
9681 let json = match serde_json:: to_string ( & content) {
97- Ok ( json) => json,
82+ Ok ( json) => json,
9883 Err ( err) => {
99- eprintln ! (
100- "{}: could not convert search results to JSON as {err}" ,
101- "ERROR" . bold( ) . red( ) ,
102- err = err. to_string( ) . red( )
103- ) ;
84+ eprintln ! ( "{}: could not convert search results to JSON as {err}" , "ERROR" . bold( ) . red( ) , err = err. to_string( ) . red( ) ) ;
10485 return serve_500 ( request) ;
10586 }
10687 } ;
10788
10889 let content_header = Header :: from_bytes ( "Content-Type" , "application/json" )
109- . expect ( "Header entered is not a garbage value" ) ;
110-
90+ . expect ( "Header entered is not a garbage value" ) ;
91+
11192 let response = Response :: from_string ( json) . with_header ( content_header) ;
11293
11394 return request. respond ( response) ;
@@ -117,45 +98,41 @@ pub fn serve_api_stats(request: Request, model: Arc<Mutex<InMemoryModel>>) -> io
11798 use serde:: Serialize ;
11899 #[ derive( Default , Serialize ) ]
119100 struct Stats {
120- doc_count : usize ,
121- unique_term_count : usize ,
101+ doc_count : usize ,
102+ unique_term_count : usize ,
122103 }
123104
124105 let model = model. lock ( ) . unwrap ( ) ;
125106 let stats = Stats {
126- doc_count : model. docs . len ( ) ,
127- unique_term_count : model. gtf . len ( ) ,
107+ doc_count : model. docs . len ( ) ,
108+ unique_term_count : model. gtf . len ( )
128109 } ;
129110
130111 let json = match serde_json:: to_string ( & stats) {
131- Ok ( json) => json,
112+ Ok ( json) => json,
132113 Err ( err) => {
133- eprintln ! (
134- "{}: could not convert search results to JSON as {err}" ,
135- "ERROR" . bold( ) . red( ) ,
136- err = err. to_string( ) . red( )
137- ) ;
114+ eprintln ! ( "{}: could not convert search results to JSON as {err}" , "ERROR" . bold( ) . red( ) , err = err. to_string( ) . red( ) ) ;
138115 return serve_500 ( request) ;
139116 }
140117 } ;
141118
142119 let content_header = Header :: from_bytes ( "Content-Type" , "application/json" )
143- . expect ( "Header entered is not a garbage value" ) ;
144-
120+ . expect ( "Header entered is not a garbage value" ) ;
121+
145122 let response = Response :: from_string ( json) . with_header ( content_header) ;
146123
147124 return request. respond ( response) ;
148125}
149126
150127pub fn serve_request ( request : Request , model : Arc < Mutex < InMemoryModel > > ) -> io:: Result < ( ) > {
151- println ! (
152- "{info}: Received request! method: [{req}], url: {url:?}" ,
153- info = "INFO" . bright_cyan( ) ,
128+ println ! ( "{info}: Received request! method: [{req}], url: {url:?}" ,
129+ info = "INFO" . bright_cyan( ) ,
154130 req = & request. method( ) . as_str( ) . bright_green( ) ,
155131 url = & request. url( )
156132 ) ;
157133
158134 match ( & request. method ( ) , request. url ( ) ) {
135+
159136 ( Method :: Get , "/" ) | ( Method :: Get , "/index.html" ) => {
160137 serve_static_file ( request, "src/index.html" , "text/html; charset=utf-8" ) ?
161138 }
@@ -164,9 +141,13 @@ pub fn serve_request(request: Request, model: Arc<Mutex<InMemoryModel>>) -> io::
164141 serve_static_file ( request, "src/index.js" , "text/javascript; charset=utf-8" ) ?
165142 }
166143
167- ( Method :: Post , "/api/search" ) => serve_api_search ( request, model) ?,
144+ ( Method :: Post , "/api/search" ) => {
145+ serve_api_search ( request, model) ?
146+ }
168147
169- ( Method :: Get , "/api/stats" ) => serve_api_stats ( request, model) ?,
148+ ( Method :: Get , "/api/stats" ) => {
149+ serve_api_stats ( request, model) ?
150+ }
170151
171152 _ => {
172153 return serve_404 ( request) ;
@@ -176,37 +157,22 @@ pub fn serve_request(request: Request, model: Arc<Mutex<InMemoryModel>>) -> io::
176157 Ok ( ( ) )
177158}
178159
160+
179161pub fn start ( address : & str , model : Arc < Mutex < InMemoryModel > > ) -> Result < ( ) , ( ) > {
180- let address_str = "http://" . to_string ( ) + & address + "/" ;
181- let server = Server :: http ( address)
182- . map_err ( |err| {
183- eprintln ! (
184- "{}: Could not create initiate server at {address} as {err}" ,
185- "ERROR" . bold( ) . red( ) ,
186- address = address. bold( ) . bright_blue( ) ,
187- err = err. to_string( ) . red( )
188- ) ;
189- exit ( 1 ) ;
190- } )
191- . unwrap ( ) ;
192-
193- println ! (
194- "{info}: Server Listening at: {address}" ,
195- info = "INFO" . bright_cyan( ) ,
196- address = address_str. cyan( )
197- ) ;
162+ let address_str = "http://" . to_string ( ) + & address + "/" ;
163+ let server = Server :: http ( address) . map_err ( |err| {
164+ eprintln ! ( "{}: Could not create initiate server at {address} as {err}" , "ERROR" . bold( ) . red( ) , address = address. bold( ) . bright_blue( ) , err = err. to_string( ) . red( ) ) ;
165+ exit ( 1 ) ;
166+ } ) . unwrap ( ) ;
167+
168+ println ! ( "{info}: Server Listening at: {address}" , info = "INFO" . bright_cyan( ) , address = address_str. cyan( ) ) ;
198169
199170 for request in server. incoming_requests ( ) {
200- serve_request ( request, Arc :: clone ( & model) )
201- . map_err ( |err| {
202- eprintln ! (
203- "{}: Failed to serve the request as {err}" ,
204- "ERROR" . bold( ) . red( ) ,
205- err = err. to_string( ) . red( )
206- ) ;
207- } )
208- . ok ( ) ; // <- Don't stop here continue serving requests
171+ serve_request ( request, Arc :: clone ( & model) ) . map_err ( |err| {
172+ eprintln ! ( "{}: Failed to serve the request as {err}" , "ERROR" . bold( ) . red( ) , err = err. to_string( ) . red( ) ) ;
173+ } ) . ok ( ) ; // <- Don't stop here continue serving requests
209174 }
210175 eprintln ! ( "{}: Server socket has shutdown" , "ERROR" . bold( ) . red( ) ) ;
211176 Ok ( ( ) )
212177}
178+
0 commit comments