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
/*!
This crate provides support for reading and writing JSON compilation database files.

A compilation database is a set of records which describe the compilation of the
source files in a given project. It describes the compiler invocation command to
compile a source module to an object file.

This database can have many forms. One well known and supported format is the JSON
compilation database, which is a simple JSON file having the list of compilation
as an array. The definition of the JSON compilation database files is done in the
LLVM project [documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html).
 */

extern crate core;

use serde::ser::{Serializer, SerializeSeq};
use serde_json::Error;

mod type_de;
mod type_ser;
mod iterator;

/// The conventional name for a compilation database file which tools are looking for.
pub const DEFAULT_FILE_NAME: &str = "compile_commands.json";

/// Represents an entry of the compilation database.
#[derive(Debug, PartialEq, Eq)]
pub struct Entry {
    /// The main translation unit source processed by this compilation step.
    /// This is used by tools as the key into the compilation database.
    /// There can be multiple command objects for the same file, for example if the same
    /// source file is compiled with different configurations.
    pub file: std::path::PathBuf,
    /// The compile command executed. This must be a valid command to rerun the exact
    /// compilation step for the translation unit in the environment the build system uses.
    /// Shell expansion is not supported.
    pub arguments: Vec<String>,
    /// The working directory of the compilation. All paths specified in the command or
    /// file fields must be either absolute or relative to this directory.
    pub directory: std::path::PathBuf,
    /// The name of the output created by this compilation step. This field is optional.
    /// It can be used to distinguish different processing modes of the same input file.
    pub output: Option<std::path::PathBuf>,
}

pub fn write(writer: impl std::io::Write, entries: impl Iterator<Item=Entry>) -> Result<(), Error> {
    let mut ser = serde_json::Serializer::new(writer);
    let mut seq = ser.serialize_seq(None)?;
    for entry in entries {
        seq.serialize_element(&entry)?;
    }
    seq.end()
}

pub fn read(reader: impl std::io::Read) -> impl Iterator<Item=Result<Entry, Error>> {
    iterator::iter_json_array(reader)
}