initial commit

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: Ife1391ed23a1e7f388b1b5eca90b9ea76a6a6964
This commit is contained in:
raf 2026-01-29 19:36:25 +03:00
commit ef28bdaeb4
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
63 changed files with 17292 additions and 0 deletions

77
src/ui_utils.rs Normal file
View file

@ -0,0 +1,77 @@
// UI utility functions for terminal formatting and interactive prompts
use std::io;
use dialoguer::{Confirm, MultiSelect, Select, theme::ColorfulTheme};
/// Creates a terminal hyperlink using OSC 8 escape sequence
/// Format: \x1b]8;;<URL>\x1b\\<TEXT>\x1b]8;;\x1b\\
pub fn hyperlink(url: &str, text: &str) -> String {
format!("\x1b]8;;{url}\x1b\\{text}\x1b]8;;\x1b\\")
}
/// Prompts user with a yes/no question
/// Returns true for yes, false for no
pub fn prompt_yes_no(question: &str, default: bool) -> io::Result<bool> {
Confirm::with_theme(&ColorfulTheme::default())
.with_prompt(question)
.default(default)
.interact()
.map_err(io::Error::other)
}
/// Prompts user to select from a list of options
/// Returns the index of the selected option
#[allow(dead_code)]
pub fn prompt_select(question: &str, options: &[&str]) -> io::Result<usize> {
Select::with_theme(&ColorfulTheme::default())
.with_prompt(question)
.items(options)
.default(0)
.interact()
.map_err(io::Error::other)
}
/// Prompts user to select multiple items from a list
/// Returns the indices of the selected options
#[allow(dead_code)]
pub fn prompt_multi_select(
question: &str,
options: &[&str],
) -> io::Result<Vec<usize>> {
MultiSelect::with_theme(&ColorfulTheme::default())
.with_prompt(question)
.items(options)
.interact()
.map_err(io::Error::other)
}
/// Creates a formatted project URL for Modrinth
#[allow(dead_code)]
pub fn modrinth_project_url(slug: &str) -> String {
format!("https://modrinth.com/mod/{slug}")
}
/// Creates a formatted project URL for `CurseForge`
#[allow(dead_code)]
pub fn curseforge_project_url(project_id: &str) -> String {
format!("https://www.curseforge.com/minecraft/mc-mods/{project_id}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hyperlink() {
let result = hyperlink("https://example.com", "Example");
assert!(result.contains("https://example.com"));
assert!(result.contains("Example"));
}
#[test]
fn test_modrinth_url() {
let url = modrinth_project_url("sodium");
assert_eq!(url, "https://modrinth.com/mod/sodium");
}
}