1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use std::net::SocketAddr;
use crate::entry_point::command_line_args::CommandLineArgument;
use crate::request::Request;
use crate::response::Response;

#[cfg(test)]
mod tests;

pub struct Log;

impl Log {
    pub fn request_response(request: &Request, response: &Response, peer_addr: &SocketAddr) -> String {
        let mut request_headers = "".to_string();
        for header in &request.headers {
            if &header.name.chars().count() > &0 {
                request_headers = [
                    request_headers,
                    "\n  ".to_string(),
                    header.name.to_string(),
                    ": ".to_string(),
                    header.value.to_string()
                ].join("");
            }
        }

        let mut response_headers = "".to_string();
        for header in &response.headers {
            if &header.name.chars().count() > &0 {
                response_headers = [
                    response_headers,
                    "\n  ".to_string(),
                    header.name.to_string(),
                    ": ".to_string(),
                    header.value.to_string()
                ].join("");
            }
        }

        let mut response_body_length = 0;
        let mut response_body_parts_number = 0;
        for content_range in &response.content_range_list {
            let boxed_parse = content_range.size.parse::<i32>();
            if boxed_parse.is_ok() {
                response_body_length += boxed_parse.unwrap();
                response_body_parts_number += 1;
            }
        }

        let log_request_response = format!("\n\nRequest (peer address is {}):\n  {} {} {}  {}\nEnd of Request\nResponse:\n  {} {} {}\n\n  Body: {} part(s), {} byte(s) total\nEnd of Response",
                                           peer_addr,
                                           &request.http_version,
                                           &request.method,
                                           &request.request_uri,
                                           request_headers,

                                           &response.status_code,
                                           &response.reason_phrase,
                                           response_headers,
                                           response_body_parts_number,
                                           response_body_length);

        log_request_response
    }

    pub fn usage_information() -> String {
        let mut log = "Usage:\n\n".to_string();
        let command_line_arg_list = CommandLineArgument::get_command_line_arg_list();
        for arg in command_line_arg_list {
            let argument_info = format!("  {} environment variable\n  -{} or --{} as command line line argument\n  {}\n\n", arg.environment_variable, arg.short_form, arg.long_form, arg._hint.unwrap());
            log = [log, argument_info].join("");
        }
        log = [log, "End of usage section\n\n".to_string()].join("");
        log
    }

    pub fn info(name: &str) -> String {
        let mut log = format!("{}\n", name).to_string();
        const VERSION: &str = env!("CARGO_PKG_VERSION");
        const AUTHORS: &str = env!("CARGO_PKG_AUTHORS");
        const REPOSITORY: &str = env!("CARGO_PKG_REPOSITORY");
        const DESCRIPTION: &str = env!("CARGO_PKG_DESCRIPTION");
        const RUST_VERSION: &str = env!("CARGO_PKG_RUST_VERSION");
        const LICENSE: &str = env!("CARGO_PKG_LICENSE");

        let version = format!("Version:       {}\n", VERSION);
        log = [log, version].join("");

        let authors = format!("Authors:       {}\n", AUTHORS);
        log = [log, authors].join("");

        let repository = format!("Repository:    {}\n", REPOSITORY);
        log = [log, repository].join("");

        let description = format!("Desciption:    {}\n", DESCRIPTION);
        log = [log, description].join("");

        let rust_version = format!("Rust Version:  {}\n", RUST_VERSION);
        log = [log, rust_version].join("");

        let license = format!("License:       {}\n", LICENSE);
        log = [log, license].join("");

        log
    }

    pub fn server_url_thread_count(protocol: &str, bind_addr: &String, thread_count: i32) -> String {
        let url = format!("Server is up and running at: {}://{}\n", protocol, &bind_addr);
        let thread_count = format!("Spawned {} thread(s) to handle incoming requests\n", thread_count);
        [url, thread_count].join("")
    }
}