project model

This commit is contained in:
Aleksey Kladov
2018-09-02 14:46:15 +03:00
parent 7fad13de73
commit 80be61ed78
11 changed files with 251 additions and 78 deletions

View File

@@ -2,30 +2,35 @@ use std::{
collections::HashMap,
path::{Path, PathBuf},
};
use libsyntax2::SmolStr;
use cargo_metadata::{metadata_run, CargoOpt};
use Result;
use crossbeam_channel::{bounded, Sender, Receiver};
use libsyntax2::SmolStr;
#[derive(Debug)]
use {
Result,
thread_watcher::ThreadWatcher,
};
#[derive(Debug, Serialize, Clone)]
pub struct CargoWorkspace {
ws_members: Vec<Package>,
packages: Vec<PackageData>,
targets: Vec<TargetData>,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, Serialize)]
pub struct Package(usize);
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, Serialize)]
pub struct Target(usize);
#[derive(Debug)]
#[derive(Debug, Serialize, Clone)]
struct PackageData {
name: SmolStr,
manifest: PathBuf,
targets: Vec<Target>
}
#[derive(Debug)]
#[derive(Debug, Serialize, Clone)]
struct TargetData {
pkg: Package,
name: SmolStr,
@@ -33,7 +38,7 @@ struct TargetData {
kind: TargetKind,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)]
pub enum TargetKind {
Bin, Lib, Example, Test, Bench, Other,
}
@@ -66,9 +71,10 @@ impl Target {
}
impl CargoWorkspace {
pub fn from_path(path: &Path) -> Result<CargoWorkspace> {
pub fn from_cargo_metadata(path: &Path) -> Result<CargoWorkspace> {
let cargo_toml = find_cargo_toml(path)?;
let meta = metadata_run(
Some(path),
Some(cargo_toml.as_path()),
true,
Some(CargoOpt::AllFeatures)
).map_err(|e| format_err!("cargo metadata failed: {}", e))?;
@@ -121,6 +127,21 @@ impl CargoWorkspace {
}
}
fn find_cargo_toml(path: &Path) -> Result<PathBuf> {
if path.ends_with("Cargo.toml") {
return Ok(path.to_path_buf());
}
let mut curr = Some(path);
while let Some(path) = curr {
let candidate = path.join("Cargo.toml");
if candidate.exists() {
return Ok(candidate);
}
curr = path.parent();
}
bail!("can't find Cargo.toml at {}", path.display())
}
impl TargetKind {
fn new(kinds: &[String]) -> TargetKind {
for kind in kinds {
@@ -136,3 +157,16 @@ impl TargetKind {
TargetKind::Other
}
}
pub fn workspace_loader() -> (Sender<PathBuf>, Receiver<Result<CargoWorkspace>>, ThreadWatcher) {
let (path_sender, path_receiver) = bounded::<PathBuf>(16);
let (ws_sender, ws_receiver) = bounded::<Result<CargoWorkspace>>(1);
let thread = ThreadWatcher::spawn("workspace loader", move || {
path_receiver
.into_iter()
.map(|path| CargoWorkspace::from_cargo_metadata(path.as_path()))
.for_each(|it| ws_sender.send(it))
});
(path_sender, ws_receiver, thread)
}