This commit is contained in:
157
src/lib.rs
Normal file
157
src/lib.rs
Normal file
@ -0,0 +1,157 @@
|
||||
pub mod flair {
|
||||
use std::{
|
||||
fs,
|
||||
thread,
|
||||
process::Command,
|
||||
collections::HashMap,
|
||||
};
|
||||
|
||||
use std::io::prelude::*;
|
||||
use std::io::BufReader;
|
||||
use regex::Regex;
|
||||
|
||||
///Holds all kinds of placeholders
|
||||
///and the methods to replace them
|
||||
#[derive(Debug)]
|
||||
struct Placeholder {
|
||||
raw: String,
|
||||
kind: PlaceholderKind,
|
||||
}
|
||||
|
||||
impl Placeholder {
|
||||
|
||||
///Method to replace a placeholder to its value
|
||||
fn replace_to_val(&self, vars: &HashMap<String, String>) -> String {
|
||||
match self.kind {
|
||||
PlaceholderKind::Cmd => {
|
||||
let (mut output, _) = run_cmd(&self.raw);
|
||||
if output.ends_with('\n') {
|
||||
output.pop();
|
||||
}
|
||||
return String::from(output);
|
||||
},
|
||||
PlaceholderKind::Var => {
|
||||
let mut value = String::new();
|
||||
if vars.contains_key(&self.raw) {
|
||||
let _ = &mut value.push_str(
|
||||
vars.get(&self.raw).unwrap()
|
||||
);
|
||||
} else {
|
||||
let _ = &mut value.push_str("UNKOWN VAR");
|
||||
}
|
||||
return value;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
enum PlaceholderKind {
|
||||
Cmd,
|
||||
Var,
|
||||
}
|
||||
|
||||
|
||||
///Takes a file and submits it for analysis.
|
||||
///Takes two values : the path of the file to analyze,
|
||||
///and an HashMap of values that can be replaced when we find a
|
||||
///%%var_name%% in our template file.
|
||||
///vars must be : HashMap<String, String> where key is var name
|
||||
///and value is the value of our var.
|
||||
pub fn analyze_file(filepath: &str, vars: HashMap<String, String>) -> String {
|
||||
let file = fs::File::open(filepath).expect(&format!("File not {} found", &filepath));
|
||||
let reader = BufReader::new(file).lines();
|
||||
let mut analyzed_lines: Vec<String> = Vec::new();
|
||||
|
||||
for line in reader {
|
||||
let mut myline = line.unwrap();
|
||||
myline = analyze_line(&mut myline, &vars);
|
||||
_ = &mut analyzed_lines.push(myline);
|
||||
}
|
||||
|
||||
return analyzed_lines.join("\n");
|
||||
}
|
||||
|
||||
|
||||
///Runs a bash command in a thread, returns the result
|
||||
///(Stdout, Stderr)
|
||||
fn run_cmd(cmd: &String) -> (String, String) {
|
||||
let cmd_clone = cmd.clone();
|
||||
let handle = thread::spawn(move || {
|
||||
return Command::new("/bin/bash")
|
||||
.args(&["-c", cmd_clone.as_str()])
|
||||
.output()
|
||||
.expect("Command failed");
|
||||
});
|
||||
|
||||
let result = handle.join().unwrap();
|
||||
let output = String::from_utf8(result.stdout).unwrap();
|
||||
let out_err = String::from_utf8(result.stderr).unwrap();
|
||||
return (output, out_err);
|
||||
}
|
||||
|
||||
|
||||
///Analyzes a line, and replaces placeholders
|
||||
///with their actual value.
|
||||
fn analyze_line<'a>(line: &'a mut String, vars: &HashMap<String, String>) -> String {
|
||||
let re = Regex::new(r"%%[^%]*%%").unwrap();
|
||||
let mut temp_line = String::from(line.as_str());
|
||||
for occurence in re.captures_iter(line) {
|
||||
//Never goes further than zero
|
||||
//println!("Found : {:?}", &occurence[0]);
|
||||
let my_ph = analyze_word(&occurence[0]);
|
||||
temp_line = temp_line.replace(&occurence[0], &my_ph.replace_to_val(&vars));
|
||||
}
|
||||
return temp_line;
|
||||
|
||||
}
|
||||
|
||||
///Used to replace individuals placeholders ("words").
|
||||
fn analyze_word(word: &str) -> Placeholder {
|
||||
let mut word = String::from(word).replace("%%", "");
|
||||
|
||||
if word.starts_with("cmd: ") {
|
||||
word = word.replace("cmd: ", "");
|
||||
return Placeholder{ kind: PlaceholderKind::Cmd, raw: word };
|
||||
} else {
|
||||
return Placeholder{ kind: PlaceholderKind::Var, raw: word };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn cmd_test() {
|
||||
let cmd = String::from("/usr/bin/echo bonjour");
|
||||
let expected = String::from("bonjour\n");
|
||||
let (outp, _) = run_cmd(&cmd);
|
||||
assert_eq!(expected, outp);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analyze_test() {
|
||||
let vars = HashMap::from([
|
||||
(String::from("name"), String::from("RustGirl")),
|
||||
]);
|
||||
let mut myline = String::from(
|
||||
"This is a test line from %%name%% \n\
|
||||
%%cmd: echo Sayonara%%"
|
||||
);
|
||||
let myresult = analyze_line(&mut myline, &vars);
|
||||
let expected = String::from(
|
||||
"This is a test line from RustGirl \n\
|
||||
Sayonara"
|
||||
);
|
||||
println!("LINE {:?}", myline);
|
||||
println!("RES {:?}", myresult);
|
||||
println!("EXPEC {:?}", expected);
|
||||
assert_eq!(myresult, expected);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
38
src/main.rs
Normal file
38
src/main.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use ssw::websrv::{
|
||||
run_server,
|
||||
WebsrvConfig,
|
||||
};
|
||||
use flair::flair::analyze_file;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::{thread, time};
|
||||
|
||||
fn update_index(vars: &HashMap<String, String>) {
|
||||
let newvars = vars.clone();
|
||||
let analyzed = analyze_file("./templates/index.html.st", newvars);
|
||||
fs::write("./static_html/index.html", analyzed).expect("Could not write index_file");
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let myvars = HashMap::from([
|
||||
(String::from("name"), String::from("Justine")),
|
||||
(String::from("surname"), String::from("Squi")),
|
||||
]);
|
||||
|
||||
update_index(&myvars);
|
||||
|
||||
let web_conf = WebsrvConfig {
|
||||
nbr_of_threads: 3,
|
||||
bind_addr: String::from("0.0.0.0:8080"),
|
||||
root_folder: String::from("./static_html"),
|
||||
};
|
||||
|
||||
run_server(web_conf);
|
||||
loop {
|
||||
thread::sleep(time::Duration::from_secs(30));
|
||||
update_index(&myvars);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user