use thread_scoped_ref::{scoped, thread_scoped_ref, with};
pub struct Person {
pub name: String,
}
impl WithName for Person {
fn name(&self) -> &str {
&self.name
}
}
pub struct Thing {
pub name: String,
}
impl WithName for Thing {
fn name(&self) -> &str {
&self.name
}
}
pub trait WithName {
fn name(&self) -> &str;
}
thread_scoped_ref!(WITH_NAME, dyn WithName);
#[test]
pub fn simple_test() {
let mut found_name = None;
let thing = Thing {
name: "A red car".to_string(),
};
scoped(&WITH_NAME, &thing, || {
found_name = with(&WITH_NAME, |maybe_with_name| {
Some(maybe_with_name.unwrap().name().to_string())
});
});
assert_eq!(found_name.unwrap(), "A red car");
}
#[test]
pub fn initially_no_value() {
let found = with(&WITH_NAME, |maybe_with_name| maybe_with_name.is_some());
assert_eq!(false, found);
}
#[test]
pub fn no_scope_no_value() {
let mut found_name = None;
let thing = Thing {
name: "A blue car".to_string(),
};
scoped(&WITH_NAME, &thing, || {
found_name = with(&WITH_NAME, |maybe_with_name| {
Some(maybe_with_name.unwrap().name().to_string())
});
});
assert_eq!(found_name.unwrap(), "A blue car");
let found = with(&WITH_NAME, |maybe_with_name| maybe_with_name.is_some());
assert_eq!(false, found);
}
#[test]
pub fn nested_scopes() {
let thing_outer_scope = Thing {
name: "A green car".to_string(),
};
let person_inner_scope = Person {
name: "Albert".to_string(),
};
scoped(&WITH_NAME, &thing_outer_scope, || {
with(&WITH_NAME, |maybe_with_name| {
assert_eq!("A green car", maybe_with_name.unwrap().name());
});
scoped(&WITH_NAME, &person_inner_scope, || {
with(&WITH_NAME, |maybe_with_name| {
assert_eq!("Albert", maybe_with_name.unwrap().name());
});
});
with(&WITH_NAME, |maybe_with_name| {
assert_eq!("A green car", maybe_with_name.unwrap().name());
});
});
}
#[test]
pub fn simple_test_manual() {
let mut found_name = None;
WITH_NAME.with(|scope| {
let person = Person {
name: "Person One".to_string(),
};
scope.scoped(&person, || {
WITH_NAME.with(|scope| {
scope.with(|maybe_with_name| {
found_name = Some(maybe_with_name.unwrap().name().to_string());
})
});
});
});
assert_eq!(found_name.unwrap(), "Person One");
}
thread_scoped_ref!(PERSON, Person);
#[test]
pub fn test_with_struct() {
let mut found_name = None;
let person = Person {
name: "Einstein".to_string(),
};
scoped(&PERSON, &person, || {
found_name = with(&PERSON, |maybe_person| {
Some(maybe_person.unwrap().name.clone())
});
});
assert_eq!(found_name.unwrap(), "Einstein");
}