git-next/src/server/config.rs

143 lines
3.4 KiB
Rust
Raw Normal View History

use std::{
collections::HashMap,
fmt::{Display, Formatter},
};
2024-04-07 13:47:39 +01:00
use serde::Deserialize;
use terrors::OneOf;
use crate::filesystem::FileSystem;
2024-04-07 16:09:16 +01:00
#[derive(Debug, PartialEq, Eq, Deserialize)]
pub struct Config {
forge: HashMap<String, Forge>,
}
#[derive(Debug, PartialEq, Eq, Deserialize)]
pub struct Forge {
forge_type: ForgeType,
hostname: String,
2024-04-07 13:47:39 +01:00
user: String,
// API Token
// Private SSH Key Path
repos: HashMap<String, String>,
}
impl Forge {
pub const fn forge_type(&self) -> &ForgeType {
&self.forge_type
}
pub fn hostname(&self) -> &str {
&self.hostname
}
pub fn user(&self) -> &str {
&self.user
}
pub fn repos(&self) -> impl Iterator<Item = (&String, &String)> {
self.repos.iter()
}
2024-04-07 13:47:39 +01:00
}
#[derive(Clone)]
pub struct ForgeName(pub String);
impl Display for ForgeName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
pub struct Hostname(pub String);
pub struct User(pub String);
pub struct ForgeDetails {
pub name: ForgeName,
pub forge_type: ForgeType,
pub hostname: Hostname,
pub user: User,
// API Token
// Private SSH Key Path
}
impl From<(&ForgeName, &Forge)> for ForgeDetails {
fn from(forge: (&ForgeName, &Forge)) -> Self {
Self {
name: forge.0.clone(),
forge_type: forge.1.forge_type.clone(),
hostname: Hostname(forge.1.hostname.clone()),
user: User(forge.1.user.clone()),
}
}
}
#[derive(Clone)]
pub struct RepoName(pub String);
impl Display for RepoName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
pub struct RepoPath(pub String);
pub struct RepoDetails {
pub name: RepoName,
pub path: RepoPath,
pub forge: ForgeDetails,
}
#[derive(Clone, Debug, PartialEq, Eq, Deserialize)]
2024-04-07 16:09:16 +01:00
pub enum ForgeType {
2024-04-07 13:47:39 +01:00
ForgeJo,
// Gitea,
// GitHub,
// GitLab,
// BitBucket,
}
impl Display for ForgeType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
2024-04-07 16:09:16 +01:00
#[allow(dead_code)]
2024-04-07 13:47:39 +01:00
impl Config {
pub(crate) fn load(fs: &FileSystem) -> Result<Self, OneOf<(std::io::Error, toml::de::Error)>> {
let str = fs.read_file("git-next-server.toml").map_err(OneOf::new)?;
toml::from_str(&str).map_err(OneOf::new)
}
pub(crate) fn forges(&self) -> impl Iterator<Item = (&String, &Forge)> {
self.forge.iter()
2024-04-07 13:47:39 +01:00
}
}
#[cfg(test)]
mod tests {
use assert2::let_assert;
2024-04-07 13:47:39 +01:00
use crate::filesystem::FileSystem;
use super::*;
#[test]
fn test_config_load() -> Result<(), OneOf<(std::io::Error, toml::de::Error)>> {
let fs = FileSystem::new_temp().map_err(OneOf::new)?;
fs.write_file(
"git-next-server.toml",
r#"
[forge.default]
forge_type = "ForgeJo"
hostname = "git.example.net"
2024-04-07 13:47:39 +01:00
user = "Bob"
[forge.default.repos]
hello = "user/world"
2024-04-07 13:47:39 +01:00
"#,
)
.map_err(OneOf::new)?;
let config = Config::load(&fs)?;
let_assert!(Some(default) = config.forge.get("default"));
assert_eq!(default.forge_type, ForgeType::ForgeJo);
assert_eq!(default.hostname, "git.example.net".to_string());
assert_eq!(default.user, "Bob".to_string());
assert_eq!(default.repos.get("hello"), Some(&"user/world".to_string()));
2024-04-07 13:47:39 +01:00
Ok(())
}
}