Skip to main content

runmat_package/source/path_project/
mod.rs

1mod freeze;
2mod load;
3mod model;
4
5use crate::{GraphError, HostCapability};
6#[cfg(not(target_arch = "wasm32"))]
7use runmat_config::project::discover_project_manifest_from;
8use runmat_config::project::{
9    discover_project_manifest_from_async, ProjectManifestLoadError, ProjectSourceIndexError,
10};
11use std::collections::BTreeSet;
12use std::path::{Path, PathBuf};
13use thiserror::Error;
14
15pub use freeze::{build_frozen_project_async, PathProjectError};
16
17use super::FrozenProject;
18
19#[derive(Debug, Error)]
20pub enum FrozenProjectError {
21    #[error(transparent)]
22    Project(#[from] PathProjectError),
23    #[error(transparent)]
24    Graph(#[from] GraphError),
25    #[error("failed to load root project manifest {path}: {source}")]
26    RootManifestLoad {
27        path: PathBuf,
28        #[source]
29        source: Box<ProjectManifestLoadError>,
30    },
31    #[error("failed to load dependency manifest {path} for dependency `{dependency}` of package `{package}`: {source}")]
32    DependencyManifestLoad {
33        package: String,
34        dependency: String,
35        path: PathBuf,
36        #[source]
37        source: Box<ProjectManifestLoadError>,
38    },
39    #[error("dependency `{dependency}` in package `{package}` points to missing manifest {path}")]
40    MissingDependencyManifest {
41        package: String,
42        dependency: String,
43        path: PathBuf,
44    },
45    #[error("dependency `{dependency}` in package `{package}` does not define a local `path`")]
46    DependencyPathRequired { package: String, dependency: String },
47    #[error("failed to build source index for package `{package}`: {source}")]
48    SourceIndex {
49        package: String,
50        #[source]
51        source: Box<ProjectSourceIndexError>,
52    },
53    #[error("dependency cycle detected while loading project composition: {cycle}")]
54    DependencyCycle { cycle: String },
55    #[error("synchronous project freezing is unavailable on WebAssembly; use the async API")]
56    SyncUnavailable,
57}
58
59pub fn discover_frozen_project_from(
60    start: &Path,
61    host_capabilities: BTreeSet<HostCapability>,
62) -> Result<Option<FrozenProject>, FrozenProjectError> {
63    #[cfg(not(target_arch = "wasm32"))]
64    {
65        let Some(manifest_path) = discover_project_manifest_from(start) else {
66            return Ok(None);
67        };
68        build_frozen_project(&manifest_path, host_capabilities).map(Some)
69    }
70    #[cfg(target_arch = "wasm32")]
71    {
72        let _ = start;
73        let _ = host_capabilities;
74        Ok(None)
75    }
76}
77
78pub async fn discover_frozen_project_from_async(
79    start: &Path,
80    host_capabilities: BTreeSet<HostCapability>,
81) -> Result<Option<FrozenProject>, FrozenProjectError> {
82    let Some(manifest_path) = discover_project_manifest_from_async(start).await else {
83        return Ok(None);
84    };
85    build_frozen_project_async(&manifest_path, host_capabilities)
86        .await
87        .map(Some)
88}
89
90pub fn build_frozen_project(
91    manifest_path: &Path,
92    host_capabilities: BTreeSet<HostCapability>,
93) -> Result<FrozenProject, FrozenProjectError> {
94    #[cfg(not(target_arch = "wasm32"))]
95    {
96        futures::executor::block_on(build_frozen_project_async(manifest_path, host_capabilities))
97    }
98    #[cfg(target_arch = "wasm32")]
99    {
100        let _ = manifest_path;
101        let _ = host_capabilities;
102        Err(FrozenProjectError::SyncUnavailable)
103    }
104}