clap_cargo_extra/
impls.rs

1use std::ffi::OsString;
2
3use cargo_metadata::Target;
4use clap_cargo::{Features, Manifest, Workspace};
5
6/// Trait for generating args. [`OsString`] is used since some args may be paths.
7pub trait Args {
8    fn to_args(&self) -> Vec<OsString>;
9}
10
11/// Trait for merging Arg structs. First struct takes precedence over second struct.
12pub trait Merge {
13    fn merge(&mut self, other: Self);
14}
15
16impl Args for Features {
17    fn to_args(&self) -> Vec<OsString> {
18        let mut args: Vec<OsString> = Vec::with_capacity(4);
19        if self.all_features {
20            args.push("--all-features".into());
21        }
22        if self.no_default_features {
23            args.push("--no-default-features".into());
24        }
25        if !self.features.is_empty() {
26            args.push("--features".into());
27            args.push(self.features.join(" ").into());
28        }
29        args
30    }
31}
32
33impl Merge for Features {
34    fn merge(&mut self, other: Self) {
35        let Features {
36            all_features,
37            no_default_features,
38            mut features,
39            ..
40        } = other;
41        self.all_features = self.all_features || all_features;
42        self.no_default_features = self.no_default_features || no_default_features;
43        self.features.append(&mut features);
44    }
45}
46
47impl Args for Manifest {
48    fn to_args(&self) -> Vec<OsString> {
49        let mut args: Vec<OsString> = Vec::with_capacity(4);
50        if let Some(manifest_path) = self.manifest_path.as_ref() {
51            args.push("--manifest-path".into());
52            args.push(manifest_path.clone().into());
53        }
54        args
55    }
56}
57
58impl Merge for Manifest {
59    fn merge(&mut self, other: Self) {
60        if self.manifest_path.is_none() {
61            self.manifest_path = other.manifest_path;
62        }
63    }
64}
65
66impl Args for Workspace {
67    fn to_args(&self) -> Vec<OsString> {
68        let mut args: Vec<OsString> = Vec::with_capacity(4);
69        if self.workspace || self.all {
70            args.push("--workspace".into());
71        }
72        for package in &self.package {
73            args.push("--package".into());
74            args.push(package.into());
75        }
76        for exclude in &self.exclude {
77            args.push("--exclude".into());
78            args.push(exclude.into());
79        }
80        args
81    }
82}
83
84impl Merge for Workspace {
85    fn merge(&mut self, other: Self) {
86        let Workspace {
87            mut package,
88            workspace,
89            all,
90            mut exclude,
91            ..
92        } = other;
93        self.package.append(&mut package);
94        self.workspace = self.workspace || workspace;
95        self.all = self.all || all;
96        self.exclude.append(&mut exclude);
97    }
98}
99
100pub trait TargetTools {
101    /// Returns the name of the wasm binary
102    /// `-` -> `_` and add `.wasm` to the end
103    fn wasm_bin_name(&self) -> String;
104
105    /// Returns the name of the binary with no extension
106    /// `-` -> `_`
107    fn bin_name(&self) -> String;
108}
109
110impl TargetTools for Target {
111    fn wasm_bin_name(&self) -> String {
112        format!("{}.wasm", self.bin_name())
113    }
114
115    fn bin_name(&self) -> String {
116        self.name.replace('-', "_")
117    }
118}