added config parsing, and the selection between multiple providers.

This commit is contained in:
2026-07-10 21:03:45 -05:00
parent 4283b1af2a
commit 8348946c3c
9 changed files with 351 additions and 32 deletions
+39 -18
View File
@@ -1,26 +1,24 @@
use crate::{
providers::{Provider, github::Github},
tui::user_select_repo,
};
use crate::{config::parse_config, providers::Provider, tui::user_select_repo};
use colored::*;
use dialoguer::{Select, theme::ColorfulTheme};
use std::io::Write;
use std::{io, process};
mod config;
mod providers;
mod tui;
const CONFIG_PATH: &str = "~/.config/clonee";
enum DefaultAnswer {
Yes,
No,
}
fn ask_yes_no(message: &str, default: Option<DefaultAnswer>) -> bool {
let options = match default {
Some(DefaultAnswer::Yes) => vec!["Yes", "No"],
Some(DefaultAnswer::No) => vec!["No", "Yes"],
None => vec!["Yes", "No"],
};
fn ask_option<T>(message: &str, options: Vec<T>) -> T
where
T: std::fmt::Display + Clone,
{
let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt(message.to_string())
.items(&options)
@@ -28,7 +26,18 @@ fn ask_yes_no(message: &str, default: Option<DefaultAnswer>) -> bool {
.interact()
.unwrap();
match options[selection] {
options[selection].clone()
}
fn ask_yes_no(message: &str, default: Option<DefaultAnswer>) -> bool {
let options: Vec<&str> = match default {
Some(DefaultAnswer::Yes) => vec!["Yes", "No"],
Some(DefaultAnswer::No) => vec!["No", "Yes"],
None => vec!["Yes", "No"],
};
// &str implements both Display and Copy!
match ask_option(message, options) {
"Yes" => true,
"No" => false,
_ => unreachable!(),
@@ -47,12 +56,24 @@ fn get_input(message: &str) -> String {
#[tokio::main]
async fn main() {
// Testing to see if github provider works.
let gh = Github {
username: "pure-sagacity".to_string(),
let config_file = format!("{}/config.toml", CONFIG_PATH);
let config = match parse_config(config_file.clone()).await {
Ok(c) => c,
Err(e) => {
let top = "Failed to parse config.".red();
let bottom = "Maybe there's an error in the config?".dimmed();
println!("{}\n{}", top, bottom);
eprintln!("Error at {}: {}", config_file, e);
process::exit(1);
}
};
let repos = gh.repositories().await.expect("Failed to get repos.");
let selected_provider = ask_option("Choose a provider:", config.provider);
let provider: crate::config::ProviderClient = selected_provider.into_provider_trait();
let repos = provider.repositories().await.expect("Failed to get repos.");
let selection = match user_select_repo(repos).await {
Ok(r) => r,
@@ -62,7 +83,7 @@ async fn main() {
}
};
match ask_yes_no("Clone the repo?", None) {
match ask_yes_no("Clone the repo?", Some(DefaultAnswer::Yes)) {
true => {
let folder: Option<String> =
if ask_yes_no("Use a custom folder?", Some(DefaultAnswer::No)) {
@@ -72,7 +93,7 @@ async fn main() {
None
};
match gh.clone(selection, folder, false).await {
match provider.clone(selection, folder, false).await {
Ok(_) => println!("Repo cloned!"),
Err(_) => {
println!("{}", "Error cloning repo.".red())