feat(notforge): add Gitea API foundation

This commit is contained in:
2026-07-11 23:33:24 -04:00
parent 3a475bc25b
commit 1a3aaf2dd9
12 changed files with 1433 additions and 3 deletions

View File

@@ -1,3 +1,4 @@
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::Path;
@@ -85,6 +86,22 @@ impl std::fmt::Display for Method {
}
}
/// Load and deserialize a TOML config file, mapping I/O and parse errors
/// into the caller's crate-specific error type.
pub fn load_toml_file<T, E, ReadError, ParseError>(
path: &Path,
read_error: ReadError,
parse_error: ParseError,
) -> Result<T, E>
where
T: DeserializeOwned,
ReadError: FnOnce(&Path, std::io::Error) -> E,
ParseError: FnOnce(&Path, toml::de::Error) -> E,
{
let content = std::fs::read_to_string(path).map_err(|err| read_error(path, err))?;
toml::from_str(&content).map_err(|err| parse_error(path, err))
}
impl Config {
pub fn load(dotfiles_dir: &Path) -> Result<Self, NotfilesError> {
let config_path = dotfiles_dir.join("notfiles.toml");
@@ -204,6 +221,10 @@ ignore = [".git", ".DS_Store", "README.md", "LICENSE", "notfiles.toml", ".notfil
mod tests {
use super::*;
fn temp_config_path(name: &str) -> std::path::PathBuf {
std::env::temp_dir().join(format!("notcore-{name}-{}.toml", std::process::id()))
}
#[test]
fn test_default_config() {
let config = Config::default();
@@ -323,4 +344,40 @@ target = "~/bin"
assert!(ssh_ignores.contains(&".git"));
assert!(ssh_ignores.contains(&"known_hosts"));
}
#[test]
fn load_toml_file_deserializes_config() {
let path = temp_config_path("load-toml-file-ok");
std::fs::write(&path, "[defaults]\ntarget = \"~/dotfiles\"\n")
.expect("test should write temporary config");
let config: Config = load_toml_file(
&path,
|path, err| format!("read {}: {err}", path.display()),
|path, err| format!("parse {}: {err}", path.display()),
)
.expect("temporary config should parse");
assert_eq!(config.defaults.target, "~/dotfiles");
std::fs::remove_file(&path).expect("test should remove temporary config");
}
#[test]
fn load_toml_file_maps_parse_error() {
let path = temp_config_path("load-toml-file-parse-error");
std::fs::write(&path, "[defaults\ntarget = \"~/dotfiles\"\n")
.expect("test should write invalid temporary config");
let result: Result<Config, String> = load_toml_file(
&path,
|path, err| format!("read {}: {err}", path.display()),
|path, err| format!("parse {}: {err}", path.display()),
);
let err = result.expect_err("invalid TOML should return parse error");
assert!(err.contains("parse "));
std::fs::remove_file(&path).expect("test should remove temporary config");
}
}