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
|
use std::path::PathBuf;
use clap::Parser;
use color_eyre::Result;
use error::{LuaXError, ReluaxError};
mod error;
mod luax;
mod server;
fn table_to_html<W: std::io::Write>(table: rlua::Table, f: &mut W) -> Result<()> {
let type_name: Option<String> = table.get("tag").unwrap();
if type_name.is_none() {
return Err(ReluaxError::LuaX(LuaXError::MissingField("tag".to_string())).into());
}
let type_name = type_name.unwrap();
write!(f, "<{}", type_name)?;
let mut children = None;
for pair in table.pairs::<String, rlua::Value>() {
let (key, value) = pair?;
if key == "tag" {
continue;
}
if key == "children" {
children = Some(value);
continue;
}
match value {
rlua::Value::Nil => write!(f, " {}=\"\"", key)?,
rlua::Value::Boolean(b) => write!(f, " {}=\"{}\"", key, b)?,
rlua::Value::Integer(i) => write!(f, " {}=\"{}\"", key, i)?,
rlua::Value::Number(n) => write!(f, " {}=\"{}\"", key, n)?,
rlua::Value::String(s) => write!(f, " {}=\"{}\"", key, s.to_str()?)?,
_ => return Err(ReluaxError::LuaX(LuaXError::WrongFieldType(key)).into()),
}
}
write!(f, ">")?;
if let Some(children) = children {
if let rlua::Value::Table(children) = children {
for child in children.sequence_values::<rlua::Value>() {
match child? {
rlua::Value::Table(child) => table_to_html(child, f)?,
rlua::Value::String(s) => write!(f, "{}", s.to_str()?)?,
_ => return Err(ReluaxError::LuaX(LuaXError::NonTableChildren).into()),
}
}
} else {
return Err(ReluaxError::LuaX(LuaXError::NonTableChildren).into());
}
}
write!(f, "</{}>", type_name)?;
Ok(())
}
#[derive(Debug, Clone, clap::Parser)]
struct Args {
#[clap(short = 'C', long = "current-dir", default_value = ".")]
current_dir: std::path::PathBuf,
#[clap(short = 'p', long = "port", default_value = "4310")]
port: u16,
}
#[tokio::main]
async fn main() -> color_eyre::Result<()> {
color_eyre::install().unwrap();
let args = Args::parse();
let current_dir = args.current_dir;
if !current_dir.is_dir() {
return Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("{} is not a directory", current_dir.display()),
)
.into());
}
std::env::set_current_dir(current_dir)?;
luax::preprocess_dir(std::env::current_dir()?.as_path())?;
println!("⛱️ Reluax files preprocessed!");
let entry = PathBuf::from("reluax.lua");
if !entry.is_file() {
return Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("{} is not a file", entry.display()),
).into());
}
server::Server::serve(args.port).await?;
Ok(())
}
|