/* * Copyright (c) 2023 Emma Tebibyte * 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, (String, u32)> { let mut out: HashMap = 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::>().as_mut_slice().join(""); let parsed_toml = match toml.parse::() { 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, (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, (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.", file_name), EX_UNAVAILABLE )); }, }; out.insert(file_name, contents); } Ok(out) }