nils_common/lib.rs
1//! # nils-common public API contracts (Task 1.2)
2//!
3//! This crate keeps runtime behavior stable. The items below are contract specifications for
4//! planned cross-CLI modules; this step is documentation-only and does not implement/export all
5//! modules yet.
6//!
7//! ## Planned module contracts (spec only)
8//!
9//! ```text
10//! // env
11//! pub fn is_truthy(input: &str) -> bool;
12//! pub fn env_truthy(name: &str) -> bool;
13//! pub fn env_truthy_or(name: &str, default: bool) -> bool;
14//! pub fn no_color_enabled() -> bool;
15//!
16//! // shell
17//! pub enum AnsiStripMode { CsiSgrOnly, CsiAnyTerminator }
18//! pub fn quote_posix_single(input: &str) -> String;
19//! pub fn strip_ansi(input: &str, mode: AnsiStripMode) -> std::borrow::Cow<'_, str>;
20//!
21//! // process (expansion on top of existing path lookup helpers)
22//! pub struct ProcessOutput {
23//! pub status: std::process::ExitStatus,
24//! pub stdout: Vec<u8>,
25//! pub stderr: Vec<u8>,
26//! }
27//! pub enum ProcessError { Io(std::io::Error), NonZero(ProcessOutput) }
28//! pub fn run_output(program: &str, args: &[&str]) -> Result<ProcessOutput, ProcessError>;
29//! pub fn run_checked(program: &str, args: &[&str]) -> Result<(), ProcessError>;
30//! pub fn run_stdout_trimmed(program: &str, args: &[&str]) -> Result<String, ProcessError>;
31//!
32//! // git
33//! pub fn is_inside_work_tree(cwd: &std::path::Path) -> Result<bool, ProcessError>;
34//! pub fn repo_root(cwd: &std::path::Path) -> Result<Option<std::path::PathBuf>, ProcessError>;
35//! pub fn rev_parse(cwd: &std::path::Path, args: &[&str]) -> Result<String, ProcessError>;
36//! pub fn rev_parse_opt(cwd: &std::path::Path, args: &[&str]) -> Result<Option<String>, ProcessError>;
37//!
38//! // clipboard
39//! pub enum ClipboardTool { Pbcopy, WlCopy, Xclip, Xsel, Clip }
40//! pub struct ClipboardPolicy<'a> {
41//! pub tool_order: &'a [ClipboardTool],
42//! pub warn_on_failure: bool,
43//! }
44//! pub enum ClipboardOutcome { Copied(ClipboardTool), SkippedNoTool, SkippedFailure }
45//! pub fn copy_best_effort(text: &str, policy: &ClipboardPolicy<'_>) -> ClipboardOutcome;
46//! ```
47//!
48//! ## Compatibility rules
49//! - `nils-common` returns structured results only; user-facing warning/error text stays in
50//! caller adapters.
51//! - Exit-code mapping stays in caller crates.
52//! - APIs stay domain-neutral and must not encode crate-specific UX policies.
53//! - Quoting and ANSI differences are expressed via explicit mode/policy parameters.
54//!
55pub mod clipboard;
56pub mod env;
57pub mod fs;
58pub mod git;
59pub mod process;
60pub mod shell;
61
62pub fn greeting(name: &str) -> String {
63 format!("Hello, {name}!")
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use pretty_assertions::assert_eq;
70
71 #[test]
72 fn greeting_formats_name() {
73 let result = greeting("Nils");
74 assert_eq!(result, "Hello, Nils!");
75 }
76}