diff --git a/Cargo.lock b/Cargo.lock index b4ebf7389..34fa66b6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1001,6 +1001,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1566,12 +1587,34 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "io-lifetimes" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + [[package]] name = "ipnet" version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +[[package]] +name = "is-terminal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + [[package]] name = "isahc" version = "0.9.14" @@ -1722,6 +1765,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + [[package]] name = "lock_api" version = "0.4.9" @@ -2638,6 +2687,20 @@ dependencies = [ "semver 1.0.14", ] +[[package]] +name = "rustix" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fdebc4b395b7fbb9ab11e462e20ed9051e7b16e42d24042c776eca0ac81b03" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + [[package]] name = "rustls" version = "0.20.6" @@ -3533,6 +3596,7 @@ name = "voicevox_core_c_api" version = "0.0.0" dependencies = [ "anyhow", + "is-terminal", "libc", "once_cell", "pretty_assertions", diff --git a/crates/voicevox_core_c_api/Cargo.toml b/crates/voicevox_core_c_api/Cargo.toml index 47f6ebf4c..695243267 100644 --- a/crates/voicevox_core_c_api/Cargo.toml +++ b/crates/voicevox_core_c_api/Cargo.toml @@ -13,6 +13,7 @@ directml = ["voicevox_core/directml"] [dependencies] voicevox_core.workspace = true +is-terminal = "0.4.2" libc = "0.2.134" once_cell.workspace = true serde_json.workspace = true diff --git a/crates/voicevox_core_c_api/src/lib.rs b/crates/voicevox_core_c_api/src/lib.rs index 7ac2b38b9..195f510ba 100644 --- a/crates/voicevox_core_c_api/src/lib.rs +++ b/crates/voicevox_core_c_api/src/lib.rs @@ -2,13 +2,15 @@ mod compatible_engine; mod helpers; use self::helpers::*; +use is_terminal::IsTerminal; use libc::c_void; use once_cell::sync::Lazy; +use std::env; use std::ffi::{CStr, CString}; +use std::io::{self, Write}; use std::os::raw::c_char; use std::ptr::null; use std::sync::{Mutex, MutexGuard}; -use std::{env, io}; use tracing_subscriber::EnvFilter; use voicevox_core::AudioQueryModel; use voicevox_core::Result; @@ -20,16 +22,35 @@ use rstest::*; type Internal = VoicevoxCore; static INTERNAL: Lazy> = Lazy::new(|| { - let _ = tracing_subscriber::fmt() - .with_env_filter(if env::var_os(EnvFilter::DEFAULT_ENV).is_some() { - EnvFilter::from_default_env() - } else { - "error,voicevox_core=info,voicevox_core_c_api=info,onnxruntime=info".into() - }) - .with_writer(io::stderr) - .try_init(); - - Internal::new_with_mutex() + let _ = init_logger(); + return Internal::new_with_mutex(); + + fn init_logger() -> std::result::Result<(), impl Sized> { + tracing_subscriber::fmt() + .with_env_filter(if env::var_os(EnvFilter::DEFAULT_ENV).is_some() { + EnvFilter::from_default_env() + } else { + "error,voicevox_core=info,voicevox_core_c_api=info,onnxruntime=info".into() + }) + .with_ansi(out().is_terminal() && env_allows_ansi()) + .with_writer(out) + .try_init() + } + + fn out() -> impl IsTerminal + Write { + io::stderr() + } + + fn env_allows_ansi() -> bool { + // https://docs.rs/termcolor/1.2.0/src/termcolor/lib.rs.html#245-291 + // ただしWindowsではPowerShellっぽかったらそのまま許可する。 + // ちゃんとやるなら`ENABLE_VIRTUAL_TERMINAL_PROCESSING`をチェックするなり、そもそも + // fwdansiとかでWin32の色に変換するべきだが、面倒。 + env::var_os("TERM").map_or( + cfg!(windows) && env::var_os("PSModulePath").is_some(), + |term| term != "dumb", + ) && env::var_os("NO_COLOR").is_none() + } }); pub(crate) fn lock_internal() -> MutexGuard<'static, Internal> {