aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/json_project.rs
blob: ee2de4c2569165561ccaab17ac1d86f7c88ee4aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! FIXME: write short doc here

use std::path::PathBuf;

use rustc_hash::FxHashSet;
use serde::Deserialize;

/// Roots and crates that compose this Rust project.
#[derive(Clone, Debug, Deserialize)]
pub struct JsonProject {
    pub(crate) roots: Vec<Root>,
    pub(crate) crates: Vec<Crate>,
}

/// A root points to the directory which contains Rust crates. rust-analyzer watches all files in
/// all roots. Roots might be nested.
#[derive(Clone, Debug, Deserialize)]
#[serde(transparent)]
pub struct Root {
    pub(crate) path: PathBuf,
}

/// 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, Deserialize)]
pub struct Crate {
    pub(crate) root_module: PathBuf,
    pub(crate) edition: Edition,
    pub(crate) deps: Vec<Dep>,

    #[serde(default)]
    pub(crate) cfg: FxHashSet<String>,

    pub(crate) out_dir: Option<PathBuf>,
    pub(crate) proc_macro_dylib_path: Option<PathBuf>,
}

#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(rename = "edition")]
pub enum Edition {
    #[serde(rename = "2015")]
    Edition2015,
    #[serde(rename = "2018")]
    Edition2018,
}

/// Identifies a crate by position in the crates array.
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[serde(transparent)]
pub struct CrateId(pub usize);

/// A dependency of a crate, identified by its id in the crates array and name.
#[derive(Clone, Debug, Deserialize)]
pub struct Dep {
    #[serde(rename = "crate")]
    pub(crate) krate: CrateId,
    pub(crate) name: String,
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn test_crate_deserialization() {
        let raw_json = json!(    {
            "crate_id": 2,
            "root_module": "this/is/a/file/path.rs",
            "deps": [
              {
                "crate": 1,
                "name": "some_dep_crate"
              },
            ],
            "edition": "2015",
            "cfg": [
              "atom_1",
              "atom_2",
              "feature=feature_1",
              "feature=feature_2",
              "other=value",
            ],

        });

        let krate: Crate = serde_json::from_value(raw_json).unwrap();

        assert!(krate.cfg.contains(&"atom_1".to_string()));
        assert!(krate.cfg.contains(&"atom_2".to_string()));
        assert!(krate.cfg.contains(&"feature=feature_1".to_string()));
        assert!(krate.cfg.contains(&"feature=feature_2".to_string()));
        assert!(krate.cfg.contains(&"other=value".to_string()));
    }
}