git.delta.rocks / jrsonnet / refs/commits / d349b9ef06a9

difftreelog

source

crates/jrsonnet-evaluator/src/dynamic.rs1.2 KiBsourcehistory
1use std::cell::OnceCell;23use jrsonnet_gcmodule::{Cc, Trace};45use crate::{bail, error::ErrorKind::InfiniteRecursionDetected, val::ThunkValue, Result};67// TODO: Replace with OnceCell once in std8#[derive(Clone, Trace)]9pub struct Pending<V: Trace + 'static>(pub Cc<OnceCell<V>>);10impl<T: Trace + 'static> Pending<T> {11	pub fn new() -> Self {12		Self(Cc::new(OnceCell::new()))13	}14	pub fn new_filled(v: T) -> Self {15		let cell = OnceCell::new();16		let _ = cell.set(v);17		Self(Cc::new(cell))18	}19	/// # Panics20	/// If wrapper is filled already21	pub fn fill(self, value: T) {22		self.023			.set(value)24			.map_err(|_| ())25			.expect("wrapper is filled already");26	}27}28impl<T: Clone + Trace + 'static> Pending<T> {29	/// # Panics30	/// If wrapper is not yet filled31	pub fn unwrap(&self) -> T {32		self.0.get().cloned().expect("pending was not filled")33	}34	pub fn try_get(&self) -> Option<T> {35		self.0.get().cloned()36	}37}3839impl<T: Trace + Clone> ThunkValue for Pending<T> {40	type Output = T;4142	fn get(self: Box<Self>) -> Result<Self::Output> {43		let Some(value) = self.0.get() else {44			bail!(InfiniteRecursionDetected);45		};46		Ok(value.clone())47	}48}4950impl<T: Trace + 'static> Default for Pending<T> {51	fn default() -> Self {52		Self::new()53	}54}