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
use std::collections::HashMap;

use crate::enums::Method;

#[derive(Debug)]
pub struct Request {
  pub method: Method,
  pub url: String,
  pub(crate) version: String,
  pub headers: HashMap<String, String>,
  pub params: HashMap<String, String>
}

impl Request {
  pub fn new(buffer: Vec<u8>) -> Result<Self,()> {
    let buffer_string = Self::parse_buffer(buffer);
    let (method, url, version, headers) = Self::parse_buffer_string(buffer_string)?;

    Ok(Self { 
      method,
      url,
      version,
      headers,
      params: HashMap::new(),
    })
  }

  fn parse_buffer(buffer: Vec<u8>) -> String{
    let string = String::from_utf8(buffer).expect("Received string is not UTF-8 ( Unable to parse stream )");
    string
  }

  fn parse_buffer_string(buffer_string: String) -> Result<(Method, String, String, HashMap<String, String>), ()>{
    if !buffer_string.is_empty(){
      let mut splitted_buffer_string = buffer_string.split("\r\n\r\n");

      match splitted_buffer_string.next(){
        Some(header_string) => {
          let (method, url, version, headers) = Self::parse_header_string(header_string);
          return Ok((method, url, version, headers));
        },
        None => (),
      }
    }

    Err(())
  }

  fn parse_header_string(header_string: &str) -> (Method, String, String, HashMap<String, String>){
    let mut splitted_header_string = header_string.split("\r\n");

    let (method, url, version) = match splitted_header_string.next(){
      Some(meta_string) => {
        Self::parse_meta_string(meta_string)
      },
      None => panic!("Unable to fetch meta values"),
    };

    let mut headers: HashMap<String, String> = HashMap::new();

    for header in splitted_header_string{
      if !header.is_empty(){
        let header = Self::parse_header(header);
        match header{
            Ok((key, value)) => {
              headers.insert(key, value);
            },
            Err(_) => break,
        }
      }
    }


    (method, url, version, headers)
  }

  fn parse_meta_string(meta_string: &str) -> (Method, String, String){
    let mut splitted_meta_string = meta_string.split(" ");
    
    //TODO: panics should be Errors
    let method = match splitted_meta_string.next(){
        Some(method) => Method::parse(method.trim()),
        None => panic!("Unable to fetch method"),
    };
    let url = match splitted_meta_string.next(){
      Some(url) => url.trim().to_string(),
      None => panic!("Unable to fetch url"),
    };
    let version = match splitted_meta_string.next(){
      Some(version) => version.trim().to_string(),
      None => panic!("Unable to fetch version"),
    };

    (method, url, version)
  }

  fn parse_header(header_string: &str) -> Result<(String, String), ()> {
    let mut key_value_string = header_string.split(":");
    let key = match key_value_string.next() {
      Some(key) => key.trim().to_string(),
      None => return Err(()),
    };
    let value = match key_value_string.next() {
      Some(value) => value.trim().to_string(),
      None => return Err(()),
    };

    Ok((key, value))
  }
}