use std::sync::Arc;
use crate::resolution::line_index;
use crate::resolution::rust::fault::RustSourceFault;
use crate::resolution::rust::identity::TargetId;
use crate::resolution::rust::inventory::RustFileInventory;
use crate::resolution::rust::project::RustProject;
use crate::resolution::supply::SourceSupply;
use super::authority;
use super::closure::{self, ClosureEntry};
use super::error::RustSnapshotError;
use super::source::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> {
line_index::find(&self.sources, path)
}
}
pub(in crate::resolution::rust) fn build<P: SourceSupply<RustFileInventory, RustSourceFault>>(
project: &RustProject,
provider: &mut P,
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::of_target(target);
let closure = closure::walk_unit(&mut store, provider, &entry, &mut failures).completed();
match (closure, failures.is_empty()) {
(Some(_), true) => Ok(RustTargetSnapshot {
target: id,
crate_root: Arc::clone(target.shared_entry_path()),
sources: store.finish(),
}),
(None, _) | (Some(_), false) => Err(refuse(&store, failures)),
}
}