use std::path::PathBuf;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum LibrarySearchPathKind {
#[default]
All,
Dep,
Crate,
Native,
Framework,
}
pub type LSPK = LibrarySearchPathKind;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct LibrarySearchPath {
pub kind: LibrarySearchPathKind,
pub path: PathBuf,
}
pub type LSP = LibrarySearchPath;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub enum LinkLibKind {
#[default]
Dylib,
Static,
Framework,
}
pub type LLK = LinkLibKind;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct LinkLib {
pub kind: Option<LinkLibKind>,
pub modifiers: Vec<String>,
pub name: String,
pub rename: Option<String>,
}
pub type LL = LinkLib;
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Emit {
pub kind: String,
pub path: Option<PathBuf>,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Extern {
pub name: String,
pub path: Option<PathBuf>,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct Info {
pub rustc: Option<String>,
pub inputs: Vec<PathBuf>,
pub help: bool,
pub version: bool,
pub verbose: bool,
pub test: bool,
pub opt_level: bool,
pub debug_info: bool,
pub crate_name: Option<String>,
pub edition: Option<String>,
pub out_dir: Option<PathBuf>,
pub out: Option<PathBuf>,
pub target: Option<String>,
pub sysroot: Option<PathBuf>,
pub error_format: Option<String>,
pub color: Option<String>,
pub json: Option<String>,
pub cap_lints: Option<String>,
pub explain: Option<String>,
pub print: Option<String>,
pub unpretty: Option<String>,
pub configs: Vec<String>, pub confchecks: Vec<String>, pub crate_types: Vec<String>, pub emits: Vec<Emit>, pub externs: Vec<Extern>, pub remap_path_prefixes: Vec<(String, String)>,
pub libpaths: Vec<LibrarySearchPath>, pub links: Vec<LinkLib>,
pub warns: Vec<String>,
pub allows: Vec<String>,
pub denies: Vec<String>,
pub forbids: Vec<String>,
pub codegen_opts: Vec<String>, pub z_opts: Vec<String>,
pub unknown: Vec<String>,
}
impl Info {
pub fn to_args(&self) -> Vec<String> {
let mut args = Vec::new();
if self.help {
args.push("--help".into());
}
if self.version {
args.push("--version".into());
}
if self.verbose {
args.push("--verbose".into());
}
if self.test {
args.push("--test".into());
}
if self.opt_level {
args.push("-O".into());
}
if self.debug_info {
args.push("-g".into());
}
if let Some(v) = &self.crate_name {
args.push(format!("--crate-name={}", v));
}
if let Some(v) = &self.edition {
args.push(format!("--edition={}", v));
}
if let Some(v) = &self.out_dir {
args.push(format!("--out-dir={}", v.display()));
}
if let Some(v) = &self.out {
args.push(format!("-o={}", v.display()));
}
if let Some(v) = &self.target {
args.push(format!("--target={}", v));
}
if let Some(v) = &self.sysroot {
args.push(format!("--sysroot={}", v.display()));
}
if let Some(v) = &self.error_format {
args.push(format!("--error-format={}", v));
}
if let Some(v) = &self.color {
args.push(format!("--color={}", v));
}
if let Some(v) = &self.json {
args.push(format!("--json={}", v));
}
if let Some(v) = &self.cap_lints {
args.push(format!("--cap-lints={}", v));
}
if let Some(v) = &self.explain {
args.push(format!("--explain={}", v));
}
if let Some(v) = &self.print {
args.push(format!("--print={}", v));
}
if let Some(v) = &self.unpretty {
args.push(format!("--unpretty={}", v));
}
for v in &self.configs {
args.push(format!("--cfg={}", v));
}
for v in &self.confchecks {
args.push(format!("--check-cfg={}", v));
}
for v in &self.crate_types {
args.push(format!("--crate-type={}", v));
}
if !self.emits.is_empty() {
let mut emit_strs = Vec::new();
for e in &self.emits {
if let Some(p) = &e.path {
emit_strs.push(format!("{}={}", e.kind, p.display()));
} else {
emit_strs.push(e.kind.clone());
}
}
args.push(format!("--emit={}", emit_strs.join(",")));
}
for e in &self.externs {
if let Some(p) = &e.path {
args.push(format!("--extern={}={}", e.name, p.display()));
} else {
args.push(format!("--extern={}", e.name));
}
}
for (from, to) in &self.remap_path_prefixes {
args.push(format!("--remap-path-prefix={}={}", from, to));
}
for lp in &self.libpaths {
let kind = match lp.kind {
LSPK::All => "",
LSPK::Dep => "dependency=",
LSPK::Crate => "crate=",
LSPK::Native => "native=",
LSPK::Framework => "framework=",
};
args.push(format!("-L{}{}", kind, lp.path.display()));
}
for l in &self.links {
let mut s = String::from("-l");
if let Some(k) = &l.kind {
let k_str = match k {
LLK::Dylib => "dylib",
LLK::Static => "static",
LLK::Framework => "framework",
};
s.push_str(k_str);
if !l.modifiers.is_empty() {
s.push(':');
s.push_str(&l.modifiers.join(","));
}
s.push('=');
}
s.push_str(&l.name);
if let Some(r) = &l.rename {
s.push(':');
s.push_str(r);
}
args.push(s);
}
for v in &self.warns {
args.push(format!("-W{}", v));
}
for v in &self.allows {
args.push(format!("-A{}", v));
}
for v in &self.denies {
args.push(format!("-D{}", v));
}
for v in &self.forbids {
args.push(format!("-F{}", v));
}
for v in &self.codegen_opts {
args.push(format!("-C{}", v));
}
for v in &self.z_opts {
args.push(format!("-Z{}", v));
}
args.extend(self.unknown.clone());
for inp in &self.inputs {
args.push(inp.to_string_lossy().into_owned());
}
args
}
}