Added startup setup

This commit is contained in:
Uber Veng
2026-05-22 01:00:57 +07:00
parent 8fe8af2962
commit 3fafc71cdd
5 changed files with 254 additions and 178 deletions

View File

@@ -29,33 +29,42 @@ fn default_theme() -> Theme {
}
}
pub fn config_path() -> PathBuf {
// Respect XDG_CONFIG_HOME; fall back to ~/.config on all platforms.
let base = std::env::var("XDG_CONFIG_HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".config")
});
base.join(env!("CARGO_PKG_NAME")).join("config.toml")
}
impl Config {
/// Returns true when a config file already exists.
pub fn exists() -> bool {
config_path().exists()
}
/// Load config from disk. Panics-safe: returns error if file is missing or malformed.
pub fn load() -> Result<Self> {
// Respect XDG_CONFIG_HOME; fall back to ~/.config on all platforms.
let config_base = std::env::var("XDG_CONFIG_HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".config")
});
let config_path = config_base
.join(env!("CARGO_PKG_NAME"))
.join("config.toml");
if !config_path.exists() {
let default = Config {
server_url: "http://localhost:8080/api/menu".to_string(),
timeout_sec: 10,
theme: default_theme(),
update_api: None,
};
fs::create_dir_all(config_path.parent().unwrap())?;
fs::write(config_path, toml::to_string_pretty(&default)?)?;
return Ok(default);
}
let content = fs::read_to_string(config_path)?;
let path = config_path();
let content = fs::read_to_string(&path)?;
Ok(toml::from_str(&content)?)
}
/// Create and persist a new config with the given server URL.
pub fn create_with_url(server_url: &str) -> Result<Self> {
let path = config_path();
let config = Config {
server_url: server_url.to_string(),
timeout_sec: 10,
theme: default_theme(),
update_api: None,
};
fs::create_dir_all(path.parent().unwrap())?;
fs::write(&path, toml::to_string_pretty(&config)?)?;
Ok(config)
}
}

View File

@@ -20,7 +20,12 @@ use tokio::sync::mpsc;
#[tokio::main]
async fn main() -> Result<()> {
let config = config::Config::load()?;
let config = if config::Config::exists() {
config::Config::load()?
} else {
let url = prompt_server_url()?;
config::Config::create_with_url(&url)?
};
enable_raw_mode()?;
let mut stdout = io::stdout();
@@ -143,6 +148,37 @@ async fn run_exec(
Ok(())
}
/// Runs before ratatui starts. Prompts for the server URL on first launch.
fn prompt_server_url() -> Result<String> {
use std::io::Write;
println!();
println!(" ╔══════════════════════════════════╗");
println!(" ║ Ostiary — первый запуск ║");
println!(" ╚══════════════════════════════════╝");
println!();
println!(" Конфиг будет сохранён в:");
println!(" {}", config::config_path().display());
println!();
loop {
print!(" URL сервера меню: ");
std::io::stdout().flush()?;
let mut url = String::new();
std::io::stdin().read_line(&mut url)?;
let url = url.trim().to_string();
if url.is_empty() {
println!(" URL не может быть пустым. Попробуйте ещё раз.\n");
continue;
}
println!();
return Ok(url);
}
}
async fn read_crossterm_event() -> Result<Option<crossterm::event::Event>> {
if crossterm::event::poll(std::time::Duration::from_millis(100))? {
Ok(Some(crossterm::event::read()?))