Skip to content

grimdork/climate-rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

climate

Minimalist toolkit for Rust command-line applications.

climate is a collection of modular crates designed to help you build fast, small, and robust command-line tools. Every crate depends only on the Rust standard library, making it a perfect fit for resource-constrained environments and systems programming.

Important

Currently optimised for Unix-like systems (Linux, macOS, BSD). Windows support is not a priority.


Crate overview

Crate Description
climate-arg Option parser with subcommands and positional arguments.
climate-cfmt printf-style colour formatting with %keyword tags.
climate-fx Small {}-style formatter with ANSI and time tokens.
climate-daemon Lifecycle utilities for background services and signal handling.
climate-prompter Interactive user prompts with support for masked secrets.
climate-paths Resolves standard config paths (XDG on Linux, Library on macOS).
climate-tab Clean, elastic tabbed columns for terminal tables.
climate-human Byte-to-human scaling (1024/1000) for readable metrics.
climate-env Environment variable fetching with default fallbacks.
climate-ini INI parser with schema and env overrides.
climate-loglines Simple, timestamped logging helpers.

Quick Start

Add whatever crate you need to Cargo.toml:

# Single crate
climate-arg = { git = "https://github.com/grimdork/climate" }
climate-cfmt = { git = "https://github.com/grimdork/climate" }
climate-human = { git = "https://github.com/grimdork/climate" }

Argument Parsing (arg)

Handle flags, subcommands, and positional arguments.

use climate_arg::{Options, VarType, GroupDefault};

let mut opt = Options::new("mytool", "Short one-line description");
opt.set_default_help(true);

// Set a boolean flag (-v, --verbose)
opt.set_option(GroupDefault, "v", "verbose", "Enable verbose output",
    false, false, VarType::Bool, &[] as &[&str]);

// Create a subcommand with a positional argument
let cmd = opt.set_command("greet", "Greet a user", GroupDefault,
    None, &[] as &[&str]);
cmd.set_positional("name", "The name to greet", "world", true, VarType::String);

match opt.parse(std::env::args().skip(1).collect()) {
    Ok(()) => {},
    Err(e) => eprintln!("Error: {e}"),
}

Colour formatting (cfmt)

Use ANSI colours with printf-style syntax.

use climate_cfmt as cfmt;

cfmt::print("%red Error:%reset file not found: '%s'\n", filename);
cfmt::println("%green Success!%reset Process completed.");

Lightweight formatting (fx)

Use simple {} placeholders plus colour and time tokens.

use climate_fx as fx;

fx::println("{green}Status:{@} {}", "ready");
fx::println("[{time}] Starting up");

Signal Handling (daemon)

Cleanly handle Ctrl+C or SIGTERM.

use climate_daemon as daemon;

// Block until termination signal
daemon::break_channel().recv().unwrap();
println!("Shutting down gracefully...");

Interactive input (prompter)

use climate_prompter as prompter;

let mut pr = prompter::Prompter::new(&[
    prompter::Question { question: "Username".into(), default: "admin".into(), secret: false },
    prompter::Question { question: "Password".into(), default: String::new(), secret: true },
]);

pr.ask().unwrap();
println!("User: {}", pr.answers[0]);
println!("Pass: {}", pr.answers[1]);

XDG & macOS path handling (paths)

use climate_paths as paths;

let dir = paths::Paths::new("myapp").unwrap();
// Returns ~/.config/myapp (Linux) or ~/Library/Application Support/myapp (macOS)
println!("Config dir: {}", dir.user_base.display());

Elastic tabulation (tab)

use climate_tab as tab;

let input = "Name Role Status\nAlice Admin Active\nBob User Offline";
let output = tab::tabulate(input, false).unwrap();
print!("{output}");

Readable sizes with rounding (human)

use climate_human as human;

println!("{}", human::uint(1572864, false)); // "1.5 MiB"
println!("{}", human::uint(1500000, true));  // "1.5 MB"

Environment helper (env)

use climate_env as env;

let host = env::get("DB_HOST", "localhost");
let debug = env::get_bool("DEBUG", false);
let port = env::get_int("PORT", 5432);
let timeout = env::get_float("REQUEST_TIMEOUT", 1.5);

INI parser (ini)

use climate_ini as ini;

let cfg = ini::unmarshal("port=8080\n[server]\nmax=1024").unwrap();
let port = cfg.get_int("", "port");

Logging (loglines)

use climate_loglines as ll;

ll::msg!("Service started on port {}", 8080);
ll::err!("Failed to bind: {}", err);
ll::cmsg!("Listening on {}", ":8080");

Core Philosophy

  • Standard library only: No third-party dependencies.
  • Unix focus: Made for systems I actually use every day.
  • Idiomatic Rust: Leverage Display, From, Error, and the type system rather than fighting them.

License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A collection of packages for command line apps in Rust, with minimal dependencies.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages