assemble_core/lazy_evaluation/
anonymous.rs

1//! Anonymous properties.
2
3use crate::__export::{ProjectResult, TaskId};
4use crate::lazy_evaluation::{IntoProvider, Provider, ProviderError};
5use crate::project::buildable::{Buildable, BuiltByContainer, IntoBuildable};
6use crate::{provider, Project};
7use std::collections::HashSet;
8use std::fmt::{Debug, Formatter};
9
10use std::sync::Arc;
11
12/// An anonymous prop is used to store provided values without needing an
13/// identifier
14#[derive(Clone)]
15pub struct AnonymousProvider<T: Clone + Send + Sync> {
16    inner: Arc<dyn Provider<T>>,
17    /// allow for extra built by definitions
18    extra_built_by: BuiltByContainer,
19}
20
21impl<T: Clone + Send + Sync> Buildable for AnonymousProvider<T> {
22    fn get_dependencies(&self, project: &Project) -> ProjectResult<HashSet<TaskId>> {
23        Ok(self
24            .inner
25            .get_dependencies(project)?
26            .into_iter()
27            .chain(self.extra_built_by.get_dependencies(project)?)
28            .collect())
29    }
30}
31
32impl<T: Clone + Send + Sync> Provider<T> for AnonymousProvider<T> {
33    fn missing_message(&self) -> String {
34        self.inner.missing_message()
35    }
36
37    fn get(&self) -> T {
38        self.inner.get()
39    }
40
41    fn try_get(&self) -> Option<T> {
42        self.inner.try_get()
43    }
44
45    fn fallible_get(&self) -> Result<T, ProviderError> {
46        self.inner.fallible_get()
47    }
48}
49
50impl<T: Clone + Send + Sync> Debug for AnonymousProvider<T> {
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        f.debug_struct("AnonymousProp").finish_non_exhaustive()
53    }
54}
55
56impl<T: Clone + Send + Sync> AnonymousProvider<T> {
57    pub fn new<P: IntoProvider<T>>(provider: P) -> Self
58    where
59        <P as IntoProvider<T>>::Provider: 'static,
60    {
61        let provider = provider.into_provider();
62        let boxed = Arc::new(provider) as Arc<dyn Provider<T>>;
63        Self {
64            inner: boxed,
65            extra_built_by: BuiltByContainer::new(),
66        }
67    }
68
69    pub fn with_value(val: T) -> Self
70    where
71        T: 'static,
72    {
73        let boxed = Arc::new(provider!(move || val.clone())) as Arc<dyn Provider<T>>;
74        Self {
75            inner: boxed,
76            extra_built_by: BuiltByContainer::new(),
77        }
78    }
79
80    /// Adds something that builds this provider
81    pub fn built_by<B: IntoBuildable>(mut self, buildable: B) -> Self
82    where
83        <B as IntoBuildable>::Buildable: 'static,
84    {
85        self.extra_built_by.add(buildable);
86        self
87    }
88}