use std::sync::Arc;
use crate::resolution::rust::identity::TargetId;
use crate::resolution::rust::project::RustProject;
use super::authority;
use super::closure::{self, ClosureEntry};
use super::error::RustSnapshotError;
use super::source::{self, RustSource};
use super::store::{SourceStore, refuse};
#[derive(Debug)]
pub struct RustTargetSnapshot {
target: TargetId,
crate_root: Arc<str>,
sources: Box<[RustSource]>,
}
impl RustTargetSnapshot {
pub fn target(&self) -> TargetId {
self.target
}
pub fn crate_root(&self) -> &str {
&self.crate_root
}
pub fn sources(&self) -> &[RustSource] {
&self.sources
}
pub fn source(&self, path: &str) -> Option<&RustSource> {
source::find(&self.sources, path)
}
}
pub(in crate::resolution::rust) fn build(
project: &RustProject,
id: TargetId,
) -> Result<RustTargetSnapshot, RustSnapshotError> {
let target = authority::validated_target(project, id)?;
let mut store = SourceStore::new(project.root(), project.limits());
let mut failures = Vec::new();
let entry = ClosureEntry {
target_name: target.name(),
entry_path: target.entry_path(),
edition: target.edition(),
};
let closure = closure::walk_unit(&mut store, &entry, &mut failures);
match (closure, failures.is_empty()) {
(Some(_), true) => Ok(RustTargetSnapshot {
target: id,
crate_root: Arc::clone(&target.entry_path),
sources: store.finish(),
}),
(None, _) | (Some(_), false) => Err(refuse(&store, failures)),
}
}