Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/copper-proc-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pistonite-cu-proc-macros"
version = "0.2.6"
version = "0.2.7"
edition = "2024"
description = "Proc-macros for Cu"
repository = "https://github.com/Pistonite/cu"
Expand All @@ -12,7 +12,7 @@ exclude = [

[dependencies.pm]
package = "pistonite-pm"
version = "0.2.5"
version = "0.2.6"
path = "../promethium"
features = ["full"]

Expand Down
27 changes: 14 additions & 13 deletions packages/copper/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pistonite-cu"
version = "0.7.4"
version = "0.8.0"
edition = "2024"
description = "Battery-included common utils to speed up development of rust tools"
repository = "https://github.com/Pistonite/cu"
Expand All @@ -11,30 +11,30 @@ exclude = [
]

[dependencies]
pistonite-cu-proc-macros = { version = "0.2.6", path = "../copper-proc-macros" }
pistonite-cu-proc-macros = { version = "0.2.7", path = "../copper-proc-macros" }

# --- Always enabled ---
anyhow = "1.0.100"
anyhow = "1.0.102"
log = "0.4.29"

# --- Command Line Interface ---
oneshot = { version = "0.1.13", optional = true }
env_filter = { version = "0.1.4", optional = true }
oneshot = { version = "0.2.1", optional = true, features = ["std"] }
env_filter = { version = "1.0.0", optional = true }
terminal_size = { version = "0.4.3", optional = true }
unicode-width = { version = "0.2.2", features = ["cjk"], optional = true }
clap = { version = "4.5.55", features = ["derive"], optional = true }
regex = { version = "1.12.2", optional = true }
ctrlc = { version = "3.5.1", optional = true }
clap = { version = "4.5.60", features = ["derive"], optional = true }
regex = { version = "1.12.3", optional = true }
ctrlc = { version = "3.5.2", optional = true }

# --- Coroutine ---
num_cpus = { version = "1.17.0", optional = true }
tokio = { version = "1.49.0", optional = true, features = [
tokio = { version = "1.50.0", optional = true, features = [
"macros", "rt-multi-thread"
] }

# --- File System ---
dunce = {version="1.0.5", optional = true}
which = {version = "8.0.0", optional = true }
which = {version = "8.0.2", optional = true }
pathdiff = {version = "0.2.3", optional=true}
filetime = { version = "0.2.27", optional = true}
glob = { version = "0.3.3", optional = true }
Expand All @@ -44,21 +44,21 @@ spin = {version = "0.10.0", optional = true} # for PIO
serde = { version = "1.0.228", features = ["derive"], optional = true }
serde_json = { version = "1.0.149", optional = true }
serde_yaml_ng = { version = "0.10.0", optional = true }
toml = { version = "0.9.11", optional = true }
toml = { version = "1.0.6", optional = true }

# derive
derive_more = { version = "2.1.1", features = ["full"], optional = true }

[target.'cfg(unix)'.dependencies]
libc = "0.2.180"
libc = "0.2.183"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.61.2", features = ["Win32_Foundation", "Win32_System_Console", "Win32_Storage_FileSystem", "Win32_Security", "Win32_System_SystemServices"] }

[dev-dependencies]

[dev-dependencies.tokio]
version = "1.49.0"
version = "1.50.0"
features = [ "macros", "rt-multi-thread", "time" ]

[features]
Expand All @@ -84,6 +84,7 @@ coroutine = [
"dep:tokio", "dep:num_cpus",
"tokio/sync", "tokio/io-util", "tokio/io-std",
"tokio/time",
"oneshot?/async",
]
coroutine-heavy = ["coroutine"] # enable heavy coroutine drived by multi-threaded tokio runtime

Expand Down
2 changes: 1 addition & 1 deletion packages/copper/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub use macros::__print_with_level;

mod thread_name;
use thread_name::THREAD_NAME;
pub use thread_name::set_thread_name;
pub use thread_name::{reset_thread_name, set_thread_name};
mod printer;

mod progress;
Expand Down
19 changes: 19 additions & 0 deletions packages/copper/src/cli/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ type AnswerRecv = oneshot::Receiver<cu::Result<Option<cu::ZString>>>;
/// -:
/// ```
#[inline(always)]
#[must_use = "prompt() returns a builder; you must call run() or co_run() to start the prompt"]
pub fn prompt(
message: impl Into<String>,
) -> PromptBuilder<cu::ZString, Cancellable, impl FnMut(&mut String) -> cu::Result<bool>> {
Expand All @@ -174,6 +175,7 @@ pub fn prompt(
/// # cu::Ok(())
/// ```
#[inline(always)]
#[must_use = "yesno() returns a builder; you must call run() or co_run() to start the prompt"]
pub fn yesno(
message: impl Into<String>,
) -> PromptBuilder<bool, DefaultIfCancel, impl FnMut(&mut String) -> cu::Result<bool>> {
Expand Down Expand Up @@ -211,6 +213,7 @@ pub struct PromptBuilder<

impl<TOutput> PromptBuilder<TOutput, Cancellable, fn(&mut String) -> cu::Result<bool>> {
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
fn new(message: impl Into<String>) -> Self {
PromptBuilder {
message: message.into(),
Expand Down Expand Up @@ -240,6 +243,7 @@ impl<TCancel: PromptCancelConfig, TValidate: FnMut(&mut String) -> cu::Result<bo
/// # Ok(()) }
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn password(mut self) -> Self {
self.is_password = true;
self
Expand All @@ -260,6 +264,7 @@ impl<TCancel: PromptCancelConfig, TValidate: FnMut(&mut String) -> cu::Result<bo
/// # Ok(()) }
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn trim_trailing_whitespace(mut self, trim: bool) -> Self {
self.trim_trailing_whitespace = trim;
self
Expand Down Expand Up @@ -308,6 +313,7 @@ impl<TCancel: PromptCancelConfig, TValidate: FnMut(&mut String) -> cu::Result<bo
/// # cu::Ok(())
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn validate_with<F>(self, validator: F) -> PromptBuilder<cu::ZString, TCancel, F>
where
F: FnMut(&mut String) -> cu::Result<bool>,
Expand Down Expand Up @@ -344,6 +350,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// # Ok(()) }
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn yesno(mut self) -> PromptBuilder<bool, Cancellable, TValidate> {
self.message.push_str(" [y/n]");
PromptBuilder {
Expand Down Expand Up @@ -378,6 +385,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// `Option<ZString>` - Just that the prompt creator has control over
/// the outcome of the prompt, rather than the prompt consumer accessing the outcome.
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn if_cancel(
self,
default: impl Into<String>,
Expand Down Expand Up @@ -407,6 +415,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// # Ok(()) }
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn or_cancel(mut self) -> PromptBuilder<cu::ZString, BailIfCancel, TValidate> {
self.message.push_str(" (Ctrl-C to cancel)");
PromptBuilder {
Expand Down Expand Up @@ -440,6 +449,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// Show the prompt and use the async runtime to wait for input.
///
/// If the user presses `Ctrl-C`, `None` will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<Option<cu::ZString>> {
check_prompt_level(false)?;
co_run_prompt_loop(
Expand Down Expand Up @@ -480,6 +490,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
///
/// If the user presses `Ctrl-C`, the default value set by [`if_cancel`](Self::if_cancel)
/// will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<cu::ZString> {
check_prompt_level(false)?;
// unwrap: safety from builder
Expand Down Expand Up @@ -523,6 +534,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
///
/// If the user presses `Ctrl-C`, an error with message "operation cancelled by user"
/// will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<cu::ZString> {
check_prompt_level(false)?;
match co_run_prompt_loop(
Expand Down Expand Up @@ -565,6 +577,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// `Option<bool>` - Just that the prompt creator has control over
/// the outcome of the prompt, rather than the prompt consumer accessing the outcome.
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn if_cancel(self, default: bool) -> PromptBuilder<bool, DefaultIfCancel, TValidate> {
PromptBuilder {
message: self.message,
Expand Down Expand Up @@ -597,6 +610,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// # }
/// ```
#[inline(always)]
#[must_use = "you must call run() or co_run() to start the prompt"]
pub fn or_cancel(mut self) -> PromptBuilder<bool, BailIfCancel, TValidate> {
self.message.push_str(" (Ctrl-C to cancel)");
PromptBuilder {
Expand Down Expand Up @@ -627,6 +641,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
/// Show the prompt and use the async runtime to wait for input.
///
/// If the user presses `Ctrl-C`, `None` will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<Option<bool>> {
if check_prompt_level(true)? {
return Ok(Some(true));
Expand Down Expand Up @@ -660,6 +675,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
///
/// If the user presses `Ctrl-C`, an error with message "operation cancelled by user"
/// will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<bool> {
if check_prompt_level(true)? {
return Ok(true);
Expand Down Expand Up @@ -694,6 +710,7 @@ impl<TValidate: FnMut(&mut String) -> cu::Result<bool>>
///
/// If the user presses `Ctrl-C`, the default value set by [`if_cancel`](Self::if_cancel)
/// will be returned.
#[cfg(feature = "coroutine")]
pub async fn co_run(self) -> cu::Result<bool> {
if check_prompt_level(true)? {
return Ok(true);
Expand Down Expand Up @@ -726,6 +743,7 @@ fn run_yesno_loop(message: String, is_password: bool) -> cu::Result<Option<bool>
)?);
Ok(Some(answer))
}
#[cfg(feature = "coroutine")]
async fn co_run_yesno_loop(message: String, is_password: bool) -> cu::Result<Option<bool>> {
let mut answer = false;
let _ = cu::some!(
Expand Down Expand Up @@ -782,6 +800,7 @@ fn run_prompt_loop<F: FnMut(&mut String) -> cu::Result<bool>>(
}
}
#[inline(always)]
#[cfg(feature = "coroutine")]
async fn co_run_prompt_loop<F: FnMut(&mut String) -> cu::Result<bool>>(
message: String,
is_password: bool,
Expand Down
6 changes: 6 additions & 0 deletions packages/copper/src/cli/thread_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ thread_local! {
pub fn set_thread_name(name: impl Into<String>) {
THREAD_NAME.with_borrow_mut(|x| *x = Some(name.into()))
}

/// Reset the current thread to not show a name
#[inline(always)]
pub fn reset_thread_name() {
THREAD_NAME.with_borrow_mut(|x| *x = None)
}
6 changes: 3 additions & 3 deletions packages/promethium/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pistonite-pm"
version = "0.2.5"
version = "0.2.6"
edition = "2024"
description = "Procedural Macro Common Utils"
repository = "https://github.com/Pistonite/cu"
Expand All @@ -12,8 +12,8 @@ exclude = [

[dependencies]
proc-macro2 = { version = "1.0.106", default-features = false }
quote = { version = "1.0.44", default-features = false }
syn = { version = "2.0.114", default-features = false }
quote = { version = "1.0.45", default-features = false }
syn = { version = "2.0.117", default-features = false }

[features]
default = [
Expand Down