use bon::bon;
use getset::Getters;
pub use self::current_working_directory::CurrentWorkingDirectory;
pub use self::error::ContextError;
use crate::cancellation::Cancellation;
use crate::output::Output;
mod current_working_directory;
mod error;
#[derive(Clone, Debug, Getters)]
pub struct Context {
#[getset(get = "pub")]
current_working_directory: CurrentWorkingDirectory,
#[getset(get = "pub")]
cancellation: Cancellation,
#[getset(get = "pub")]
output: Output,
}
#[bon]
impl Context {
#[builder]
pub fn new(
#[builder(into)] current_working_directory: Option<CurrentWorkingDirectory>,
#[builder(default)] cancellation: Cancellation,
output: Output,
) -> Result<Self, ContextError> {
let current_working_directory = match current_working_directory {
Some(cwd) => cwd,
None => CurrentWorkingDirectory::try_from_env()?,
};
Ok(Self {
current_working_directory,
cancellation,
output,
})
}
}
#[cfg(test)]
mod tests {
#![allow(clippy::missing_panics_doc)]
use std::path::Path;
use super::*;
use crate::event::event_channel;
fn test_output() -> Output {
let (sender, _receiver) = event_channel();
Output::new(sender)
}
#[test]
fn new_with_cancellation_uses_provided_token() {
let cancellation = Cancellation::new();
cancellation.cancel();
let context = Context::builder()
.current_working_directory(Path::new("/tmp"))
.cancellation(cancellation)
.output(test_output())
.build()
.expect("should create context");
assert!(context.cancellation().is_cancelled());
}
#[test]
fn new_with_cwd_uses_provided_value() {
let context = Context::builder()
.current_working_directory(Path::new("/tmp"))
.output(test_output())
.build()
.expect("should create context");
assert_eq!(context.current_working_directory().get(), Path::new("/tmp"));
}
#[test]
fn new_with_defaults_detects_cwd() {
let expected = std::env::current_dir().expect("should get current dir");
let context = Context::builder()
.output(test_output())
.build()
.expect("should create context");
assert_eq!(context.current_working_directory().get(), expected);
}
#[test]
fn new_with_defaults_has_uncancelled_token() {
let context = Context::builder()
.current_working_directory(Path::new("/tmp"))
.output(test_output())
.build()
.expect("should create context");
assert!(!context.cancellation().is_cancelled());
}
#[test]
fn trait_send() {
fn assert_send<T: Send>() {}
assert_send::<Context>();
}
#[test]
fn trait_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<Context>();
}
#[test]
fn trait_unpin() {
fn assert_unpin<T: Unpin>() {}
assert_unpin::<Context>();
}
}