135 lines
3.3 KiB
Rust
135 lines
3.3 KiB
Rust
/*
|
|
* Copyright (c) 2023 Emma Tebibyte <emma@tebibyte.media>
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*
|
|
* This file is part of Plaque.
|
|
*
|
|
* Plaque is free software: you can redistribute it and/or modify it under the
|
|
* terms of the GNU Affero General Public License as published by the Free
|
|
* Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version.
|
|
*
|
|
* Plaque is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
*/
|
|
|
|
use std::{
|
|
collections::HashMap,
|
|
io::{ Read },
|
|
fs::{ File, ReadDir },
|
|
};
|
|
|
|
use tl::{ ParserOptions, VDomGuard };
|
|
use toml::Value;
|
|
use yacexits::*;
|
|
|
|
pub fn get_contents(
|
|
dir: ReadDir,
|
|
) -> Result<HashMap<String, (String, Value)>, (String, u32)> {
|
|
let mut out: HashMap<String, (String, Value)> = HashMap::new();
|
|
let mut md: String;
|
|
let mut toml = String::new();
|
|
|
|
let mut files = match read_files(dir) {
|
|
Ok(files) => files,
|
|
Err(err) => return Err(err),
|
|
};
|
|
|
|
for entry in files.drain() {
|
|
let (file_name, contents) = entry;
|
|
let mut lines = contents.lines();
|
|
|
|
if lines.next() == Some("+++\n") {
|
|
let mut line = lines.next();
|
|
|
|
while line.unwrap() != "+++\n" {
|
|
toml.push_str(&mut line.unwrap());
|
|
line = lines.next();
|
|
}
|
|
md = lines.collect::<Vec<&str>>().as_mut_slice().join("");
|
|
|
|
let parsed_toml = match toml.parse::<Value>() {
|
|
Ok(val) => val,
|
|
Err(_) => {
|
|
return Err((
|
|
format!(
|
|
"{}: Could not parse TOML.",
|
|
file_name,
|
|
),
|
|
EX_DATAERR,
|
|
));
|
|
},
|
|
};
|
|
|
|
out.insert(file_name, (md, parsed_toml));
|
|
}
|
|
}
|
|
Ok(out)
|
|
}
|
|
|
|
pub fn get_templates(
|
|
dir: ReadDir,
|
|
) -> Result<HashMap<String, VDomGuard>, (String, u32)> {
|
|
let mut out = HashMap::new();
|
|
|
|
let mut files = match read_files(dir) {
|
|
Ok(files) => files,
|
|
Err(err) => return Err(err),
|
|
};
|
|
|
|
for entry in files.drain() {
|
|
let (file_name, contents) = entry;
|
|
|
|
let dom = match unsafe {
|
|
tl::parse_owned(contents, ParserOptions::default())
|
|
} {
|
|
Ok(dom) => dom,
|
|
Err(err) => return Err((format!("{:?}", err), EX_DATAERR)),
|
|
};
|
|
|
|
out.insert(file_name, dom);
|
|
}
|
|
Ok(out)
|
|
}
|
|
|
|
pub fn read_files(
|
|
dir: ReadDir,
|
|
) -> Result<HashMap<String, String>, (String, u32)> {
|
|
let mut out = HashMap::new();
|
|
|
|
for entry in dir {
|
|
let mut buf = Vec::new();
|
|
let file = match entry {
|
|
Ok(file) => file,
|
|
Err(_) => break,
|
|
};
|
|
|
|
let file_name = match file.file_name().into_string() {
|
|
Ok(name) => name,
|
|
Err(_) => {
|
|
return Err((format!("Invalid file name."), EX_DATAERR));
|
|
},
|
|
};
|
|
let contents = match File::open(&file_name) {
|
|
Ok(mut md_file) => {
|
|
md_file.read_to_end(&mut buf).unwrap();
|
|
String::from_utf8(buf).unwrap()
|
|
},
|
|
Err(_) => {
|
|
return Err((
|
|
format!("No such file or directory."),
|
|
EX_UNAVAILABLE
|
|
));
|
|
},
|
|
};
|
|
|
|
out.insert(file_name, contents);
|
|
}
|
|
Ok(out)
|
|
}
|