pesde 0.7.3

A package manager for the Luau programming language, supporting multiple runtimes including Roblox and Lune
Documentation
use crate::cli::auth::Tokens;
use anyhow::Context as _;
use fs_err::tokio as fs;
use serde::{Deserialize, Serialize};
use tracing::instrument;

use super::config_path;

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct CliConfig {
	#[serde(
		serialize_with = "crate::util::serialize_gix_url",
		deserialize_with = "crate::util::deserialize_gix_url"
	)]
	pub default_index: gix::Url,

	pub tokens: Tokens,

	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub last_checked_updates: Option<(jiff::Timestamp, semver::Version)>,
}

impl Default for CliConfig {
	fn default() -> Self {
		Self {
			default_index: "https://github.com/pesde-pkg/index".try_into().unwrap(),

			tokens: Tokens::default(),

			last_checked_updates: None,
		}
	}
}

#[instrument(level = "trace")]
pub async fn read_config() -> anyhow::Result<CliConfig> {
	let config_string = match fs::read_to_string(config_path()?).await {
		Ok(config_string) => config_string,
		Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
			return Ok(CliConfig::default());
		}
		Err(e) => return Err(e).context("failed to read config file"),
	};

	let config = toml::from_str(&config_string).context("failed to parse config file")?;

	Ok(config)
}

#[instrument(level = "trace")]
pub async fn write_config(config: &CliConfig) -> anyhow::Result<()> {
	let config_string = toml::to_string(config).context("failed to serialize config")?;
	let config_path = config_path()?;

	if let Some(parent) = config_path.parent() {
		fs::create_dir_all(parent)
			.await
			.context("failed to create config parent directories")?;
	}

	fs::write(config_path, config_string)
		.await
		.context("failed to write config file")?;

	Ok(())
}