From eac24d52e672c0a9c118e8969bf1b839c3e7f1f3 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Sunkara Date: Thu, 13 Aug 2020 12:05:30 +0200 Subject: Rename ra_project_model -> project_model --- crates/project_model/src/project_json.rs | 143 +++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 crates/project_model/src/project_json.rs (limited to 'crates/project_model/src/project_json.rs') diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs new file mode 100644 index 000000000..e3f3163f6 --- /dev/null +++ b/crates/project_model/src/project_json.rs @@ -0,0 +1,143 @@ +//! FIXME: write short doc here + +use std::path::PathBuf; + +use paths::{AbsPath, AbsPathBuf}; +use ra_db::{CrateId, CrateName, Dependency, Edition}; +use rustc_hash::FxHashMap; +use serde::{de, Deserialize}; + +use crate::cfg_flag::CfgFlag; + +/// Roots and crates that compose this Rust project. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ProjectJson { + pub(crate) crates: Vec, +} + +/// A crate points to the root module of a crate and lists the dependencies of the crate. This is +/// useful in creating the crate graph. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Crate { + pub(crate) root_module: AbsPathBuf, + pub(crate) edition: Edition, + pub(crate) deps: Vec, + pub(crate) cfg: Vec, + pub(crate) target: Option, + pub(crate) env: FxHashMap, + pub(crate) proc_macro_dylib_path: Option, + pub(crate) is_workspace_member: bool, + pub(crate) include: Vec, + pub(crate) exclude: Vec, +} + +impl ProjectJson { + pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson { + ProjectJson { + crates: data + .crates + .into_iter() + .map(|crate_data| { + let is_workspace_member = crate_data.is_workspace_member.unwrap_or_else(|| { + crate_data.root_module.is_relative() + && !crate_data.root_module.starts_with("..") + || crate_data.root_module.starts_with(base) + }); + let root_module = base.join(crate_data.root_module); + let (include, exclude) = match crate_data.source { + Some(src) => { + let absolutize = |dirs: Vec| { + dirs.into_iter().map(|it| base.join(it)).collect::>() + }; + (absolutize(src.include_dirs), absolutize(src.exclude_dirs)) + } + None => (vec![root_module.parent().unwrap().to_path_buf()], Vec::new()), + }; + + Crate { + root_module, + edition: crate_data.edition.into(), + deps: crate_data + .deps + .into_iter() + .map(|dep_data| Dependency { + crate_id: CrateId(dep_data.krate as u32), + name: dep_data.name, + }) + .collect::>(), + cfg: crate_data.cfg, + target: crate_data.target, + env: crate_data.env, + proc_macro_dylib_path: crate_data + .proc_macro_dylib_path + .map(|it| base.join(it)), + is_workspace_member, + include, + exclude, + } + }) + .collect::>(), + } + } +} + +#[derive(Deserialize)] +pub struct ProjectJsonData { + crates: Vec, +} + +#[derive(Deserialize)] +struct CrateData { + root_module: PathBuf, + edition: EditionData, + deps: Vec, + #[serde(default)] + cfg: Vec, + target: Option, + #[serde(default)] + env: FxHashMap, + proc_macro_dylib_path: Option, + is_workspace_member: Option, + source: Option, +} + +#[derive(Deserialize)] +#[serde(rename = "edition")] +enum EditionData { + #[serde(rename = "2015")] + Edition2015, + #[serde(rename = "2018")] + Edition2018, +} + +impl From for Edition { + fn from(data: EditionData) -> Self { + match data { + EditionData::Edition2015 => Edition::Edition2015, + EditionData::Edition2018 => Edition::Edition2018, + } + } +} + +#[derive(Deserialize)] +struct DepData { + /// Identifies a crate by position in the crates array. + #[serde(rename = "crate")] + krate: usize, + #[serde(deserialize_with = "deserialize_crate_name")] + name: CrateName, +} + +#[derive(Deserialize)] +struct CrateSource { + include_dirs: Vec, + exclude_dirs: Vec, +} + +fn deserialize_crate_name<'de, D>(de: D) -> Result +where + D: de::Deserializer<'de>, +{ + let name = String::deserialize(de)?; + CrateName::new(&name).map_err(|err| de::Error::custom(format!("invalid crate name: {:?}", err))) +} -- cgit v1.2.3