use rustest::*;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct Global<Source>(::rustest::SharedFixtureValue<Source>)
where
Source: SubFixture;
impl<Source> Fixture for Global<Source>
where
Source: SubFixture,
{
type Type = Source::Type;
type Proxy = Proxy<Source>;
}
impl<Source> ::std::ops::Deref for Global<Source>
where
Source: SubFixture,
{
type Target = <Self as ::rustest::Fixture>::Type;
fn deref(&self) -> &Self::Target {
&self.0
}
}
pub struct Proxy<Source: SubFixture> {
inner: Arc<Mutex<LazyValue<Source, (Source::Proxy,)>>>,
name: Option<String>,
}
impl<Source: SubFixture> Duplicate for Proxy<Source> {
fn duplicate(&self) -> Self {
Self {
inner: self.inner.clone(),
name: self.name.clone(),
}
}
}
impl<Source: SubFixture> TestName for Proxy<Source> {
fn name(&self) -> Option<String> {
self.name.clone()
}
}
impl<Source: SubFixture> Proxy<Source>
where
ProxyCombination<(Source::Proxy,)>: TestName,
{
fn new(proxy: ProxyCombination<(Source::Proxy,)>) -> Self {
let name = proxy.name();
let inner = proxy.into();
Self {
inner: Arc::new(Mutex::new(inner)),
name,
}
}
}
impl<Source: SubFixture> FixtureProxy for Proxy<Source> {
type Fixt = Global<Source>;
const SCOPE: FixtureScope = FixtureScope::Global;
fn setup(ctx: &mut TestContext) -> Vec<Self> {
if let Some(b) = ctx.get() {
return b;
}
let proxies = ProxyMatrix::<(Source::Proxy,)>::setup(ctx);
let inners = proxies
.into_iter()
.map(|b| Self::new(b))
.collect::<Vec<_>>();
ctx.add::<Self>(inners.duplicate());
inners
}
fn build(self) -> FixtureCreationResult<Self::Fixt> {
let inner = self
.inner
.lock()
.unwrap()
.get(|CallArgs((source,))| Ok((source, None)))?;
Ok(Global(inner))
}
}