Skip to content

Commit 6323b0d

Browse files
committed
feat(config): add config module with multi-profile TOML deserialization
- Config, Profile and RepoEntry structs with serde::Deserialize - RepoEntry::clone_url() builds authenticated URL per provider (github, gitlab, bitbucket) - RepoEntry::cache_path() returns ~/.cache/git-reports/{profile}/{provider}/{owner}/{name} - load_config() reads and parses config.toml
1 parent b361d18 commit 6323b0d

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

src/config.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use serde::Deserialize;
2+
use std::fs;
3+
use std::path::Path;
4+
5+
#[derive(Debug, Clone, Deserialize)]
6+
pub struct Config {
7+
pub profile: Vec<Profile>,
8+
}
9+
10+
#[derive(Debug, Clone, Deserialize)]
11+
pub struct Profile {
12+
pub name: String,
13+
pub email: String,
14+
pub token: String,
15+
#[serde(default)]
16+
pub repo: Vec<RepoEntry>,
17+
}
18+
19+
#[derive(Debug, Clone, Deserialize)]
20+
pub struct RepoEntry {
21+
pub provider: String, // github | gitlab | bitbucket
22+
pub owner: String,
23+
pub name: String,
24+
}
25+
26+
impl RepoEntry {
27+
/// Construye la URL de clone con el token embebido según el provider.
28+
pub fn clone_url(&self, token: &str) -> String {
29+
match self.provider.as_str() {
30+
"github" => format!(
31+
"https://{}@github.com/{}/{}.git",
32+
token, self.owner, self.name
33+
),
34+
"gitlab" => format!(
35+
"https://oauth2:{}@gitlab.com/{}/{}.git",
36+
token, self.owner, self.name
37+
),
38+
"bitbucket" => format!(
39+
"https://x-token-auth:{}@bitbucket.org/{}/{}.git",
40+
token, self.owner, self.name
41+
),
42+
other => format!(
43+
"https://{}@{}/{}/{}.git",
44+
token, other, self.owner, self.name
45+
),
46+
}
47+
}
48+
49+
/// Devuelve la ruta de caché local para este repo.
50+
/// ~/.cache/git-reports/{profile_name}/{provider}/{owner}/{name}
51+
pub fn cache_path(&self, profile_name: &str) -> std::path::PathBuf {
52+
let base = dirs_next::cache_dir()
53+
.unwrap_or_else(|| std::path::PathBuf::from("/tmp"))
54+
.join("git-reports")
55+
.join(profile_name)
56+
.join(&self.provider)
57+
.join(&self.owner)
58+
.join(&self.name);
59+
base
60+
}
61+
}
62+
63+
/// Carga y deserializa el archivo config.toml desde la ruta indicada.
64+
pub fn load_config(path: &str) -> Result<Config, String> {
65+
let content = fs::read_to_string(Path::new(path))
66+
.map_err(|e| format!("No se pudo leer '{}': {}", path, e))?;
67+
toml::from_str::<Config>(&content)
68+
.map_err(|e| format!("Error al parsear '{}': {}", path, e))
69+
}

0 commit comments

Comments
 (0)