Skip to content

Commit

Permalink
fix(unsafe): Remove unsafe code in favor of OnceLock (#20)
Browse files Browse the repository at this point in the history
This also simplifies the code a bit
  • Loading branch information
Property404 authored Nov 12, 2024
1 parent 5973c20 commit 4b299e2
Showing 1 changed file with 20 additions and 17 deletions.
37 changes: 20 additions & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
//! ```
#![allow(clippy::bool_to_int_with_if)]

use std::cell::UnsafeCell;
use std::env;
use std::sync::Once;
use std::sync::OnceLock;

/// possible stream sources
#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -159,16 +158,6 @@ pub fn on(stream: Stream) -> Option<ColorLevel> {
translate_level(supports_color(stream))
}

struct CacheCell(UnsafeCell<Option<ColorLevel>>);

unsafe impl Sync for CacheCell {}

static INIT: [Once; 2] = [Once::new(), Once::new()];
static ON_CACHE: [CacheCell; 2] = [
CacheCell(UnsafeCell::new(None)),
CacheCell(UnsafeCell::new(None)),
];

macro_rules! assert_stream_in_bounds {
($($variant:ident)*) => {
$(
Expand All @@ -187,12 +176,10 @@ be returned from then on.
If you expect your environment to change between calls, use [`on`]
*/
pub fn on_cached(stream: Stream) -> Option<ColorLevel> {
let stream_index = stream as usize;
INIT[stream_index].call_once(|| unsafe {
*ON_CACHE[stream_index].0.get() = translate_level(supports_color(stream));
});
static CACHE: [OnceLock<Option<ColorLevel>>; 2] = [OnceLock::new(), OnceLock::new()];

unsafe { *ON_CACHE[stream_index].0.get() }
let stream_index = stream as usize;
*CACHE[stream_index].get_or_init(|| translate_level(supports_color(stream)))
}

/**
Expand Down Expand Up @@ -254,6 +241,22 @@ mod tests {
assert_eq!(on(Stream::Stdout), None);
}

#[test]
#[cfg_attr(miri, ignore)]
fn test_on_cached() {
let _test_guard = TEST_LOCK.lock().unwrap();
set_up();
env::set_var("IGNORE_IS_TERMINAL", "1");

env::set_var("CLICOLOR", "1");
assert!(on(Stream::Stdout).is_some());
assert!(on_cached(Stream::Stdout).is_some());

env::set_var("CLICOLOR", "0");
assert!(on(Stream::Stdout).is_none());
assert!(on_cached(Stream::Stdout).is_some());
}

#[test]
#[cfg_attr(miri, ignore)]
fn test_clicolor_force_ansi() {
Expand Down

0 comments on commit 4b299e2

Please sign in to comment.