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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
pub mod page_manager {
use std::collections::HashMap;
use std::io::Read;
use crate::log::{log_more_text_writer, log_text_writer, LogTypeTag};
/// 현재 파일 정보 반환
fn get_this_name() -> String {
return String::from("main/server/page_manager");
}
/// 변수 반환 함수 지정
pub type GetPageTemplateVar = Box<dyn Send + (Fn() -> String) + 'static>;
/// 모든 페이지 Struct
pub struct AllPages {
pub pages: Option<HashMap<String, PageInfo>>
}
/// 페이지 정보 Struct
pub struct PageInfo {
pub file_path: String,
pub is_access: bool
}
/// 페이지 HTML 정보 Struct
pub struct PageFileReadInfo {
pub value : Option<String>,
pub is_success : IsPageFileReadSuccess
}
/// 페이지 HTML 정보 불러오기 작업 성공 여부 Enum
#[derive(PartialEq)]
pub enum IsPageFileReadSuccess {
SUCCESS, FAIL, NO_DATA
}
/// 페이지 리스트
/// 주의: 페이지 추가시 경로는 모두 소문자로 입력
pub static mut ALL_PAGES : AllPages = AllPages {
pages: None
};
/// HTML 파일 Reader
///
/// # Examples
///
/// ```
/// read_page(String::from("/hello.html"))
/// ```
///
/// # Argument
/// page_path : HTTP 경로
///
/// all_pages : 모든 페이지 정보
///
/// # Return
/// PageFileReadInfo 구조체
pub fn read_page(page_path : String) -> PageFileReadInfo {
let mut read_result : PageFileReadInfo = PageFileReadInfo {
value: None,
is_success: IsPageFileReadSuccess::NO_DATA,
};
unsafe {
match &ALL_PAGES.pages {
Some(map) => {
if map.contains_key(&page_path.to_lowercase()) {
let page_info = map.get(&page_path.to_lowercase());
match page_info {
Some(page_info) => {
if page_info.is_access {
let mut read_value = std::fs::File::open(&page_info.file_path);
match read_value {
Ok(mut value) => {
let mut contents = String::new();
match value.read_to_string(&mut contents) {
Ok(_) => {
read_result.value = Some(contents);
read_result.is_success = IsPageFileReadSuccess::SUCCESS;
}
Err(error) => {
read_result.is_success = IsPageFileReadSuccess::FAIL;
// 로그 출력
println!("{}", log_more_text_writer(error.to_string(), get_this_name(), LogTypeTag::WARNING, String::from(&page_info.file_path)));
}
}
},
Err(error) => {
read_result.is_success = IsPageFileReadSuccess::FAIL;
// 로그 출력
println!("{}", log_more_text_writer(error.to_string(), get_this_name(), LogTypeTag::WARNING, String::from(&page_info.file_path)));
}
}
}else {
read_result.is_success = IsPageFileReadSuccess::FAIL;
}
},
None => {
read_result.is_success = IsPageFileReadSuccess::NO_DATA;
}
}
}
},
None => {
read_result.is_success = IsPageFileReadSuccess::NO_DATA;
}
}
}
return read_result;
}
/// Page template parser
pub fn page_template_parser(html : String, var : HashMap<String, GetPageTemplateVar>) -> String {
// 기본 Tag
let tag_root = String::from("<#>");
let tag_var = String::from(format!("{}var", tag_root));
let tag_control = String::from(format!("{}control", tag_root));
// 제어문 Tag
let tag_control_for = String::from(format!("{}.for", tag_control));
let tag_control_for_end = String::from(format!("{}.for_end", tag_control));
// HTML 반환
return if html.contains(&tag_root) && html.contains("\n") {
let mut new_html = String::from(html.clone());
// 변수 치환
for (var_name, fun_value) in var {
let value : String = fun_value();
new_html = new_html.replace(&String::from(format!("{}.{}", &tag_var, var_name)), &value);
}
// 오류 확인
if new_html.contains(&tag_var) {
// 로그 출력
print_html_parse_error();
return html;
}
// 제어문 컴파일
let mut control_new_html = String::from(&new_html);
let mut control_split = control_new_html.split("\r\n");
let mut control_split : Vec<&str> = control_split.collect();
let mut control_for_enable : bool = false;
let mut control_for_replace : String = String::new();
let mut control_for_text : String = String::new();
let mut control_for_new_text : String = String::new();
let mut control_for_start : usize = 0;
let mut control_for_end : usize = 0;
for control_line in control_split {
// For 문 확인
if control_line.contains(&tag_control_for) && !control_line.contains(&tag_control_for_end) {
// 변수 초기화
control_for_text.clear();
control_for_new_text.clear();
control_for_replace.clear();
control_for_start = 0;
control_for_end = 0;
// For 문 분석
let data = control_line.clone().replace(&tag_control_for, "").replace(" ", "");
// 오류 확인
if !data.contains(",") {
// 로그 출력
print_html_parse_error();
return html;
}
// For 문 데이터
let data : Vec<&str> = data.split(",").collect();
if data.len() >= 2 {
control_for_start = match data[0].parse() {
Ok(value) => value,
Err(_) => 0
};
control_for_end = match data[1].parse() {
Ok(value) => value,
Err(_) => 0
};
control_for_replace.push_str(&String::from(format!("{}\r\n", &control_line)));
control_for_enable = true;
}else {
control_for_enable = false;
}
}
// For 문 내용 확인
if control_for_enable && !control_line.contains(&tag_control_for) && !control_line.contains(&tag_control_for_end) {
control_for_text.push_str(&control_line);
control_for_replace.push_str(&String::from(format!("{}\r\n", &control_line)));
}
// For 문 종료 확인
if control_line.contains(&tag_control_for_end) && control_for_enable {
control_for_enable = false;
control_for_replace.push_str(&String::from(format!("{}\r\n", &control_line)));
for _ in control_for_start..control_for_end {
control_for_new_text.push_str(&String::from(format!("{}\r\n", &control_for_text)));
}
new_html = new_html.replace(&control_for_replace, &control_for_new_text);
}
}
new_html
}else {
html
}
}
/// HTML 파싱 오류 출력
fn print_html_parse_error() {
// 로그 출력
println!("{}", log_text_writer(String::from("Syntax error, unknown error while parsing HTML from engine."), get_this_name(), LogTypeTag::WARNING));
}
}