use std::path::Path;
use pedant_types::SourceProvider;
use super::dependency::RustDependency;
use super::error::RustProjectError;
use super::fault::RustSourceFault;
use super::identity::{PackageId, ProjectAuthority, TargetId, index_of};
use super::inventory::RustFileInventory;
use super::limits::ResolutionLimits;
use super::load;
use super::manifest::ManifestFingerprint;
use super::package::RustPackage;
use super::provider::RustSourceProvider;
use super::snapshot::{
RustPackageSnapshot, RustPackageSnapshotError, RustResolutionSnapshot, RustSnapshotError,
RustTargetSnapshot, build_package_snapshot, build_resolution_snapshot, build_target_snapshot,
};
use super::target::RustTarget;
#[derive(Debug)]
pub struct RustProject {
pub(super) root: Box<Path>,
pub(super) limits: ResolutionLimits,
pub(super) authority: ProjectAuthority,
pub(super) manifests: Box<[ManifestFingerprint]>,
pub(super) packages: Box<[RustPackage]>,
pub(super) targets: Box<[RustTarget]>,
pub(super) dependencies: Box<[RustDependency]>,
}
impl RustProject {
pub fn load(root: &Path, limits: ResolutionLimits) -> Result<Self, RustProjectError> {
load::load_project(root, limits)
}
pub fn root(&self) -> &Path {
&self.root
}
pub fn limits(&self) -> ResolutionLimits {
self.limits
}
pub fn packages(&self) -> &[RustPackage] {
&self.packages
}
pub fn workspace_members(&self) -> impl Iterator<Item = &RustPackage> {
self.packages
.iter()
.filter(|package| package.is_workspace_member())
}
pub fn package(&self, id: PackageId) -> Option<&RustPackage> {
select(id.authority(), self.authority, id.index())
.and_then(|index| self.packages.get(index))
}
pub fn targets(&self) -> &[RustTarget] {
&self.targets
}
pub fn target(&self, id: TargetId) -> Option<&RustTarget> {
select(id.authority(), self.authority, id.index()).and_then(|index| self.targets.get(index))
}
pub fn package_targets(&self, package: PackageId) -> impl Iterator<Item = &RustTarget> {
self.targets
.iter()
.filter(move |target| target.package() == package)
}
pub fn dependencies(&self) -> &[RustDependency] {
&self.dependencies
}
pub fn snapshot_target(
&self,
target: TargetId,
) -> Result<RustTargetSnapshot, RustSnapshotError> {
build_target_snapshot(self, &mut private_provider(self), target)
}
pub fn snapshot_package_primary_targets(
&self,
package: PackageId,
) -> Result<RustPackageSnapshot, RustPackageSnapshotError> {
build_package_snapshot(self, &mut private_provider(self), package)
}
pub fn snapshot_resolution(
&self,
target: TargetId,
) -> Result<RustResolutionSnapshot, RustSnapshotError> {
build_resolution_snapshot(self, &mut private_provider(self), target)
}
pub fn snapshot_resolution_with_provider<P>(
&self,
provider: &mut P,
target: TargetId,
) -> Result<RustResolutionSnapshot, RustSnapshotError>
where
P: SourceProvider<RustFileInventory>,
P::Error: Into<RustSourceFault>,
{
build_resolution_snapshot(self, provider, target)
}
pub fn package_dependencies(
&self,
package: PackageId,
) -> impl Iterator<Item = &RustDependency> {
self.dependencies
.iter()
.filter(move |dependency| dependency.source() == package)
}
}
fn select(issuing: ProjectAuthority, project: ProjectAuthority, index: u32) -> Option<usize> {
match issuing == project {
true => Some(index_of(index)),
false => None,
}
}
fn private_provider(project: &RustProject) -> RustSourceProvider {
RustSourceProvider::at_project_root(project.root.to_path_buf(), project.limits)
}