]> git.proxmox.com Git - cargo.git/blob - src/cargo/core/manifest.rs
Auto merge of #6679 - dwijnand:exclude-mia-package, r=alexcrichton
[cargo.git] / src / cargo / core / manifest.rs
1 use std::collections::{BTreeMap, HashMap};
2 use std::fmt;
3 use std::hash::{Hash, Hasher};
4 use std::path::{Path, PathBuf};
5 use std::rc::Rc;
6
7 use semver::Version;
8 use serde::ser;
9 use serde::Serialize;
10 use url::Url;
11
12 use crate::core::interning::InternedString;
13 use crate::core::profiles::Profiles;
14 use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
15 use crate::core::{Edition, Feature, Features, WorkspaceConfig};
16 use crate::util::errors::*;
17 use crate::util::toml::TomlManifest;
18 use crate::util::{short_hash, Config, Filesystem};
19
20 pub enum EitherManifest {
21 Real(Manifest),
22 Virtual(VirtualManifest),
23 }
24
25 /// Contains all the information about a package, as loaded from a `Cargo.toml`.
26 #[derive(Clone, Debug)]
27 pub struct Manifest {
28 summary: Summary,
29 targets: Vec<Target>,
30 links: Option<String>,
31 warnings: Warnings,
32 exclude: Vec<String>,
33 include: Vec<String>,
34 metadata: ManifestMetadata,
35 custom_metadata: Option<toml::Value>,
36 profiles: Profiles,
37 publish: Option<Vec<String>>,
38 publish_lockfile: bool,
39 replace: Vec<(PackageIdSpec, Dependency)>,
40 patch: HashMap<Url, Vec<Dependency>>,
41 workspace: WorkspaceConfig,
42 original: Rc<TomlManifest>,
43 features: Features,
44 edition: Edition,
45 im_a_teapot: Option<bool>,
46 default_run: Option<String>,
47 metabuild: Option<Vec<String>>,
48 }
49
50 /// When parsing `Cargo.toml`, some warnings should silenced
51 /// if the manifest comes from a dependency. `ManifestWarning`
52 /// allows this delayed emission of warnings.
53 #[derive(Clone, Debug)]
54 pub struct DelayedWarning {
55 pub message: String,
56 pub is_critical: bool,
57 }
58
59 #[derive(Clone, Debug)]
60 pub struct Warnings(Vec<DelayedWarning>);
61
62 #[derive(Clone, Debug)]
63 pub struct VirtualManifest {
64 replace: Vec<(PackageIdSpec, Dependency)>,
65 patch: HashMap<Url, Vec<Dependency>>,
66 workspace: WorkspaceConfig,
67 profiles: Profiles,
68 warnings: Warnings,
69 features: Features,
70 }
71
72 /// General metadata about a package which is just blindly uploaded to the
73 /// registry.
74 ///
75 /// Note that many of these fields can contain invalid values such as the
76 /// homepage, repository, documentation, or license. These fields are not
77 /// validated by cargo itself, but rather it is up to the registry when uploaded
78 /// to validate these fields. Cargo will itself accept any valid TOML
79 /// specification for these values.
80 #[derive(PartialEq, Clone, Debug)]
81 pub struct ManifestMetadata {
82 pub authors: Vec<String>,
83 pub keywords: Vec<String>,
84 pub categories: Vec<String>,
85 pub license: Option<String>,
86 pub license_file: Option<String>,
87 pub description: Option<String>, // Not in Markdown
88 pub readme: Option<String>, // File, not contents
89 pub homepage: Option<String>, // URL
90 pub repository: Option<String>, // URL
91 pub documentation: Option<String>, // URL
92 pub badges: BTreeMap<String, BTreeMap<String, String>>,
93 pub links: Option<String>,
94 }
95
96 #[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
97 pub enum LibKind {
98 Lib,
99 Rlib,
100 Dylib,
101 ProcMacro,
102 Other(String),
103 }
104
105 impl LibKind {
106 /// Returns the argument suitable for `--crate-type` to pass to rustc.
107 pub fn crate_type(&self) -> &str {
108 match *self {
109 LibKind::Lib => "lib",
110 LibKind::Rlib => "rlib",
111 LibKind::Dylib => "dylib",
112 LibKind::ProcMacro => "proc-macro",
113 LibKind::Other(ref s) => s,
114 }
115 }
116
117 pub fn linkable(&self) -> bool {
118 match *self {
119 LibKind::Lib | LibKind::Rlib | LibKind::Dylib | LibKind::ProcMacro => true,
120 LibKind::Other(..) => false,
121 }
122 }
123 }
124
125 impl fmt::Debug for LibKind {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 self.crate_type().fmt(f)
128 }
129 }
130
131 impl<'a> From<&'a String> for LibKind {
132 fn from(string: &'a String) -> Self {
133 match string.as_ref() {
134 "lib" => LibKind::Lib,
135 "rlib" => LibKind::Rlib,
136 "dylib" => LibKind::Dylib,
137 "proc-macro" => LibKind::ProcMacro,
138 s => LibKind::Other(s.to_string()),
139 }
140 }
141 }
142
143 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
144 pub enum TargetKind {
145 Lib(Vec<LibKind>),
146 Bin,
147 Test,
148 Bench,
149 ExampleLib(Vec<LibKind>),
150 ExampleBin,
151 CustomBuild,
152 }
153
154 impl ser::Serialize for TargetKind {
155 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
156 where
157 S: ser::Serializer,
158 {
159 use self::TargetKind::*;
160 match *self {
161 Lib(ref kinds) => s.collect_seq(kinds.iter().map(LibKind::crate_type)),
162 Bin => ["bin"].serialize(s),
163 ExampleBin | ExampleLib(_) => ["example"].serialize(s),
164 Test => ["test"].serialize(s),
165 CustomBuild => ["custom-build"].serialize(s),
166 Bench => ["bench"].serialize(s),
167 }
168 }
169 }
170
171 impl fmt::Debug for TargetKind {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 use self::TargetKind::*;
174 match *self {
175 Lib(ref kinds) => kinds.fmt(f),
176 Bin => "bin".fmt(f),
177 ExampleBin | ExampleLib(_) => "example".fmt(f),
178 Test => "test".fmt(f),
179 CustomBuild => "custom-build".fmt(f),
180 Bench => "bench".fmt(f),
181 }
182 }
183 }
184
185 impl TargetKind {
186 pub fn description(&self) -> &'static str {
187 match self {
188 TargetKind::Lib(..) => "lib",
189 TargetKind::Bin => "bin",
190 TargetKind::Test => "integration-test",
191 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => "example",
192 TargetKind::Bench => "bench",
193 TargetKind::CustomBuild => "build-script",
194 }
195 }
196 }
197
198 /// Information about a binary, a library, an example, etc. that is part of the
199 /// package.
200 #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
201 pub struct Target {
202 kind: TargetKind,
203 name: String,
204 // Note that the `src_path` here is excluded from the `Hash` implementation
205 // as it's absolute currently and is otherwise a little too brittle for
206 // causing rebuilds. Instead the hash for the path that we send to the
207 // compiler is handled elsewhere.
208 src_path: TargetSourcePath,
209 required_features: Option<Vec<String>>,
210 tested: bool,
211 benched: bool,
212 doc: bool,
213 doctest: bool,
214 harness: bool, // whether to use the test harness (--test)
215 for_host: bool,
216 proc_macro: bool,
217 edition: Edition,
218 }
219
220 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
221 pub enum TargetSourcePath {
222 Path(PathBuf),
223 Metabuild,
224 }
225
226 impl TargetSourcePath {
227 pub fn path(&self) -> Option<&Path> {
228 match self {
229 TargetSourcePath::Path(path) => Some(path.as_ref()),
230 TargetSourcePath::Metabuild => None,
231 }
232 }
233
234 pub fn is_path(&self) -> bool {
235 match self {
236 TargetSourcePath::Path(_) => true,
237 _ => false,
238 }
239 }
240 }
241
242 impl Hash for TargetSourcePath {
243 fn hash<H: Hasher>(&self, _: &mut H) {
244 // ...
245 }
246 }
247
248 impl fmt::Debug for TargetSourcePath {
249 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250 match self {
251 TargetSourcePath::Path(path) => path.fmt(f),
252 TargetSourcePath::Metabuild => "metabuild".fmt(f),
253 }
254 }
255 }
256
257 impl From<PathBuf> for TargetSourcePath {
258 fn from(path: PathBuf) -> Self {
259 assert!(path.is_absolute(), "`{}` is not absolute", path.display());
260 TargetSourcePath::Path(path)
261 }
262 }
263
264 #[derive(Serialize)]
265 struct SerializedTarget<'a> {
266 /// Is this a `--bin bin`, `--lib`, `--example ex`?
267 /// Serialized as a list of strings for historical reasons.
268 kind: &'a TargetKind,
269 /// Corresponds to `--crate-type` compiler attribute.
270 /// See https://doc.rust-lang.org/reference/linkage.html
271 crate_types: Vec<&'a str>,
272 name: &'a str,
273 src_path: Option<&'a PathBuf>,
274 edition: &'a str,
275 #[serde(rename = "required-features", skip_serializing_if = "Option::is_none")]
276 required_features: Option<Vec<&'a str>>,
277 }
278
279 impl ser::Serialize for Target {
280 fn serialize<S: ser::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
281 let src_path = match &self.src_path {
282 TargetSourcePath::Path(p) => Some(p),
283 // Unfortunately getting the correct path would require access to
284 // target_dir, which is not available here.
285 TargetSourcePath::Metabuild => None,
286 };
287 SerializedTarget {
288 kind: &self.kind,
289 crate_types: self.rustc_crate_types(),
290 name: &self.name,
291 src_path,
292 edition: &self.edition.to_string(),
293 required_features: self
294 .required_features
295 .as_ref()
296 .map(|rf| rf.iter().map(|s| &**s).collect()),
297 }
298 .serialize(s)
299 }
300 }
301
302 compact_debug! {
303 impl fmt::Debug for Target {
304 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
305 let (default, default_name) = {
306 match &self.kind {
307 TargetKind::Lib(kinds) => {
308 (
309 Target::lib_target(
310 &self.name,
311 kinds.clone(),
312 self.src_path().path().unwrap().to_path_buf(),
313 self.edition,
314 ),
315 format!("lib_target({:?}, {:?}, {:?}, {:?})",
316 self.name, kinds, self.src_path, self.edition),
317 )
318 }
319 TargetKind::CustomBuild => {
320 match self.src_path {
321 TargetSourcePath::Path(ref path) => {
322 (
323 Target::custom_build_target(
324 &self.name,
325 path.to_path_buf(),
326 self.edition,
327 ),
328 format!("custom_build_target({:?}, {:?}, {:?})",
329 self.name, path, self.edition),
330 )
331 }
332 TargetSourcePath::Metabuild => {
333 (
334 Target::metabuild_target(&self.name),
335 format!("metabuild_target({:?})", self.name),
336 )
337 }
338 }
339 }
340 _ => (
341 Target::new(self.src_path.clone(), self.edition),
342 format!("with_path({:?}, {:?})", self.src_path, self.edition),
343 ),
344 }
345 };
346 [debug_the_fields(
347 kind
348 name
349 src_path
350 required_features
351 tested
352 benched
353 doc
354 doctest
355 harness
356 for_host
357 proc_macro
358 edition
359 )]
360 }
361 }
362 }
363
364 impl Manifest {
365 pub fn new(
366 summary: Summary,
367 targets: Vec<Target>,
368 exclude: Vec<String>,
369 include: Vec<String>,
370 links: Option<String>,
371 metadata: ManifestMetadata,
372 custom_metadata: Option<toml::Value>,
373 profiles: Profiles,
374 publish: Option<Vec<String>>,
375 publish_lockfile: bool,
376 replace: Vec<(PackageIdSpec, Dependency)>,
377 patch: HashMap<Url, Vec<Dependency>>,
378 workspace: WorkspaceConfig,
379 features: Features,
380 edition: Edition,
381 im_a_teapot: Option<bool>,
382 default_run: Option<String>,
383 original: Rc<TomlManifest>,
384 metabuild: Option<Vec<String>>,
385 ) -> Manifest {
386 Manifest {
387 summary,
388 targets,
389 warnings: Warnings::new(),
390 exclude,
391 include,
392 links,
393 metadata,
394 custom_metadata,
395 profiles,
396 publish,
397 replace,
398 patch,
399 workspace,
400 features,
401 edition,
402 original,
403 im_a_teapot,
404 default_run,
405 publish_lockfile,
406 metabuild,
407 }
408 }
409
410 pub fn dependencies(&self) -> &[Dependency] {
411 self.summary.dependencies()
412 }
413 pub fn exclude(&self) -> &[String] {
414 &self.exclude
415 }
416 pub fn include(&self) -> &[String] {
417 &self.include
418 }
419 pub fn metadata(&self) -> &ManifestMetadata {
420 &self.metadata
421 }
422 pub fn name(&self) -> InternedString {
423 self.package_id().name()
424 }
425 pub fn package_id(&self) -> PackageId {
426 self.summary.package_id()
427 }
428 pub fn summary(&self) -> &Summary {
429 &self.summary
430 }
431 pub fn targets(&self) -> &[Target] {
432 &self.targets
433 }
434 pub fn version(&self) -> &Version {
435 self.package_id().version()
436 }
437 pub fn warnings_mut(&mut self) -> &mut Warnings {
438 &mut self.warnings
439 }
440 pub fn warnings(&self) -> &Warnings {
441 &self.warnings
442 }
443 pub fn profiles(&self) -> &Profiles {
444 &self.profiles
445 }
446 pub fn publish(&self) -> &Option<Vec<String>> {
447 &self.publish
448 }
449 pub fn publish_lockfile(&self) -> bool {
450 self.publish_lockfile
451 }
452 pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] {
453 &self.replace
454 }
455 pub fn original(&self) -> &TomlManifest {
456 &self.original
457 }
458 pub fn patch(&self) -> &HashMap<Url, Vec<Dependency>> {
459 &self.patch
460 }
461 pub fn links(&self) -> Option<&str> {
462 self.links.as_ref().map(|s| &s[..])
463 }
464
465 pub fn workspace_config(&self) -> &WorkspaceConfig {
466 &self.workspace
467 }
468
469 pub fn features(&self) -> &Features {
470 &self.features
471 }
472
473 pub fn set_summary(&mut self, summary: Summary) {
474 self.summary = summary;
475 }
476
477 pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Manifest {
478 Manifest {
479 summary: self.summary.map_source(to_replace, replace_with),
480 ..self
481 }
482 }
483
484 pub fn feature_gate(&self) -> CargoResult<()> {
485 if self.im_a_teapot.is_some() {
486 self.features
487 .require(Feature::test_dummy_unstable())
488 .chain_err(|| {
489 failure::format_err!(
490 "the `im-a-teapot` manifest key is unstable and may \
491 not work properly in England"
492 )
493 })?;
494 }
495
496 if self.default_run.is_some() {
497 self.features
498 .require(Feature::default_run())
499 .chain_err(|| failure::format_err!("the `default-run` manifest key is unstable"))?;
500 }
501
502 Ok(())
503 }
504
505 // Just a helper function to test out `-Z` flags on Cargo
506 pub fn print_teapot(&self, config: &Config) {
507 if let Some(teapot) = self.im_a_teapot {
508 if config.cli_unstable().print_im_a_teapot {
509 println!("im-a-teapot = {}", teapot);
510 }
511 }
512 }
513
514 pub fn edition(&self) -> Edition {
515 self.edition
516 }
517
518 pub fn custom_metadata(&self) -> Option<&toml::Value> {
519 self.custom_metadata.as_ref()
520 }
521
522 pub fn default_run(&self) -> Option<&str> {
523 self.default_run.as_ref().map(|s| &s[..])
524 }
525
526 pub fn metabuild(&self) -> Option<&Vec<String>> {
527 self.metabuild.as_ref()
528 }
529
530 pub fn metabuild_path(&self, target_dir: Filesystem) -> PathBuf {
531 let hash = short_hash(&self.package_id());
532 target_dir
533 .into_path_unlocked()
534 .join(".metabuild")
535 .join(format!("metabuild-{}-{}.rs", self.name(), hash))
536 }
537 }
538
539 impl VirtualManifest {
540 pub fn new(
541 replace: Vec<(PackageIdSpec, Dependency)>,
542 patch: HashMap<Url, Vec<Dependency>>,
543 workspace: WorkspaceConfig,
544 profiles: Profiles,
545 features: Features,
546 ) -> VirtualManifest {
547 VirtualManifest {
548 replace,
549 patch,
550 workspace,
551 profiles,
552 warnings: Warnings::new(),
553 features,
554 }
555 }
556
557 pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] {
558 &self.replace
559 }
560
561 pub fn patch(&self) -> &HashMap<Url, Vec<Dependency>> {
562 &self.patch
563 }
564
565 pub fn workspace_config(&self) -> &WorkspaceConfig {
566 &self.workspace
567 }
568
569 pub fn profiles(&self) -> &Profiles {
570 &self.profiles
571 }
572
573 pub fn warnings_mut(&mut self) -> &mut Warnings {
574 &mut self.warnings
575 }
576
577 pub fn warnings(&self) -> &Warnings {
578 &self.warnings
579 }
580
581 pub fn features(&self) -> &Features {
582 &self.features
583 }
584 }
585
586 impl Target {
587 fn new(src_path: TargetSourcePath, edition: Edition) -> Target {
588 Target {
589 kind: TargetKind::Bin,
590 name: String::new(),
591 src_path,
592 required_features: None,
593 doc: false,
594 doctest: false,
595 harness: true,
596 for_host: false,
597 proc_macro: false,
598 edition,
599 tested: true,
600 benched: true,
601 }
602 }
603
604 fn with_path(src_path: PathBuf, edition: Edition) -> Target {
605 Target::new(TargetSourcePath::from(src_path), edition)
606 }
607
608 pub fn lib_target(
609 name: &str,
610 crate_targets: Vec<LibKind>,
611 src_path: PathBuf,
612 edition: Edition,
613 ) -> Target {
614 Target {
615 kind: TargetKind::Lib(crate_targets),
616 name: name.to_string(),
617 doctest: true,
618 doc: true,
619 ..Target::with_path(src_path, edition)
620 }
621 }
622
623 pub fn bin_target(
624 name: &str,
625 src_path: PathBuf,
626 required_features: Option<Vec<String>>,
627 edition: Edition,
628 ) -> Target {
629 Target {
630 kind: TargetKind::Bin,
631 name: name.to_string(),
632 required_features,
633 doc: true,
634 ..Target::with_path(src_path, edition)
635 }
636 }
637
638 /// Builds a `Target` corresponding to the `build = "build.rs"` entry.
639 pub fn custom_build_target(name: &str, src_path: PathBuf, edition: Edition) -> Target {
640 Target {
641 kind: TargetKind::CustomBuild,
642 name: name.to_string(),
643 for_host: true,
644 benched: false,
645 tested: false,
646 ..Target::with_path(src_path, edition)
647 }
648 }
649
650 pub fn metabuild_target(name: &str) -> Target {
651 Target {
652 kind: TargetKind::CustomBuild,
653 name: name.to_string(),
654 for_host: true,
655 benched: false,
656 tested: false,
657 ..Target::new(TargetSourcePath::Metabuild, Edition::Edition2018)
658 }
659 }
660
661 pub fn example_target(
662 name: &str,
663 crate_targets: Vec<LibKind>,
664 src_path: PathBuf,
665 required_features: Option<Vec<String>>,
666 edition: Edition,
667 ) -> Target {
668 let kind = if crate_targets.is_empty()
669 || crate_targets
670 .iter()
671 .all(|t| *t == LibKind::Other("bin".into()))
672 {
673 TargetKind::ExampleBin
674 } else {
675 TargetKind::ExampleLib(crate_targets)
676 };
677
678 Target {
679 kind,
680 name: name.to_string(),
681 required_features,
682 tested: false,
683 benched: false,
684 ..Target::with_path(src_path, edition)
685 }
686 }
687
688 pub fn test_target(
689 name: &str,
690 src_path: PathBuf,
691 required_features: Option<Vec<String>>,
692 edition: Edition,
693 ) -> Target {
694 Target {
695 kind: TargetKind::Test,
696 name: name.to_string(),
697 required_features,
698 benched: false,
699 ..Target::with_path(src_path, edition)
700 }
701 }
702
703 pub fn bench_target(
704 name: &str,
705 src_path: PathBuf,
706 required_features: Option<Vec<String>>,
707 edition: Edition,
708 ) -> Target {
709 Target {
710 kind: TargetKind::Bench,
711 name: name.to_string(),
712 required_features,
713 tested: false,
714 ..Target::with_path(src_path, edition)
715 }
716 }
717
718 pub fn name(&self) -> &str {
719 &self.name
720 }
721 pub fn crate_name(&self) -> String {
722 self.name.replace("-", "_")
723 }
724 pub fn src_path(&self) -> &TargetSourcePath {
725 &self.src_path
726 }
727 pub fn set_src_path(&mut self, src_path: TargetSourcePath) {
728 self.src_path = src_path;
729 }
730 pub fn required_features(&self) -> Option<&Vec<String>> {
731 self.required_features.as_ref()
732 }
733 pub fn kind(&self) -> &TargetKind {
734 &self.kind
735 }
736 pub fn tested(&self) -> bool {
737 self.tested
738 }
739 pub fn harness(&self) -> bool {
740 self.harness
741 }
742 pub fn documented(&self) -> bool {
743 self.doc
744 }
745 pub fn for_host(&self) -> bool {
746 self.for_host
747 }
748 pub fn proc_macro(&self) -> bool {
749 self.proc_macro
750 }
751 pub fn edition(&self) -> Edition {
752 self.edition
753 }
754 pub fn benched(&self) -> bool {
755 self.benched
756 }
757 pub fn doctested(&self) -> bool {
758 self.doctest
759 }
760
761 pub fn doctestable(&self) -> bool {
762 match self.kind {
763 TargetKind::Lib(ref kinds) => kinds
764 .iter()
765 .any(|k| *k == LibKind::Rlib || *k == LibKind::Lib || *k == LibKind::ProcMacro),
766 _ => false,
767 }
768 }
769
770 pub fn allows_underscores(&self) -> bool {
771 self.is_bin() || self.is_example() || self.is_custom_build()
772 }
773
774 pub fn is_lib(&self) -> bool {
775 match self.kind {
776 TargetKind::Lib(_) => true,
777 _ => false,
778 }
779 }
780
781 pub fn is_dylib(&self) -> bool {
782 match self.kind {
783 TargetKind::Lib(ref libs) => libs.iter().any(|l| *l == LibKind::Dylib),
784 _ => false,
785 }
786 }
787
788 pub fn is_cdylib(&self) -> bool {
789 let libs = match self.kind {
790 TargetKind::Lib(ref libs) => libs,
791 _ => return false,
792 };
793 libs.iter().any(|l| match *l {
794 LibKind::Other(ref s) => s == "cdylib",
795 _ => false,
796 })
797 }
798
799 pub fn linkable(&self) -> bool {
800 match self.kind {
801 TargetKind::Lib(ref kinds) => kinds.iter().any(|k| k.linkable()),
802 _ => false,
803 }
804 }
805
806 pub fn is_bin(&self) -> bool {
807 self.kind == TargetKind::Bin
808 }
809
810 pub fn is_example(&self) -> bool {
811 match self.kind {
812 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => true,
813 _ => false,
814 }
815 }
816
817 pub fn is_bin_example(&self) -> bool {
818 // Needed for --all-examples in contexts where only runnable examples make sense
819 match self.kind {
820 TargetKind::ExampleBin => true,
821 _ => false,
822 }
823 }
824
825 pub fn is_test(&self) -> bool {
826 self.kind == TargetKind::Test
827 }
828 pub fn is_bench(&self) -> bool {
829 self.kind == TargetKind::Bench
830 }
831 pub fn is_custom_build(&self) -> bool {
832 self.kind == TargetKind::CustomBuild
833 }
834
835 /// Returns the arguments suitable for `--crate-type` to pass to rustc.
836 pub fn rustc_crate_types(&self) -> Vec<&str> {
837 match self.kind {
838 TargetKind::Lib(ref kinds) | TargetKind::ExampleLib(ref kinds) => {
839 kinds.iter().map(LibKind::crate_type).collect()
840 }
841 TargetKind::CustomBuild
842 | TargetKind::Bench
843 | TargetKind::Test
844 | TargetKind::ExampleBin
845 | TargetKind::Bin => vec!["bin"],
846 }
847 }
848
849 pub fn can_lto(&self) -> bool {
850 match self.kind {
851 TargetKind::Lib(ref v) => {
852 !v.contains(&LibKind::Rlib)
853 && !v.contains(&LibKind::Dylib)
854 && !v.contains(&LibKind::Lib)
855 }
856 _ => true,
857 }
858 }
859
860 pub fn set_tested(&mut self, tested: bool) -> &mut Target {
861 self.tested = tested;
862 self
863 }
864 pub fn set_benched(&mut self, benched: bool) -> &mut Target {
865 self.benched = benched;
866 self
867 }
868 pub fn set_doctest(&mut self, doctest: bool) -> &mut Target {
869 self.doctest = doctest;
870 self
871 }
872 pub fn set_for_host(&mut self, for_host: bool) -> &mut Target {
873 self.for_host = for_host;
874 self
875 }
876 pub fn set_proc_macro(&mut self, proc_macro: bool) -> &mut Target {
877 self.proc_macro = proc_macro;
878 self
879 }
880 pub fn set_edition(&mut self, edition: Edition) -> &mut Target {
881 self.edition = edition;
882 self
883 }
884 pub fn set_harness(&mut self, harness: bool) -> &mut Target {
885 self.harness = harness;
886 self
887 }
888 pub fn set_doc(&mut self, doc: bool) -> &mut Target {
889 self.doc = doc;
890 self
891 }
892 }
893
894 impl fmt::Display for Target {
895 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
896 match self.kind {
897 TargetKind::Lib(..) => write!(f, "Target(lib)"),
898 TargetKind::Bin => write!(f, "Target(bin: {})", self.name),
899 TargetKind::Test => write!(f, "Target(test: {})", self.name),
900 TargetKind::Bench => write!(f, "Target(bench: {})", self.name),
901 TargetKind::ExampleBin | TargetKind::ExampleLib(..) => {
902 write!(f, "Target(example: {})", self.name)
903 }
904 TargetKind::CustomBuild => write!(f, "Target(script)"),
905 }
906 }
907 }
908
909 impl Warnings {
910 fn new() -> Warnings {
911 Warnings(Vec::new())
912 }
913
914 pub fn add_warning(&mut self, s: String) {
915 self.0.push(DelayedWarning {
916 message: s,
917 is_critical: false,
918 })
919 }
920
921 pub fn add_critical_warning(&mut self, s: String) {
922 self.0.push(DelayedWarning {
923 message: s,
924 is_critical: true,
925 })
926 }
927
928 pub fn warnings(&self) -> &[DelayedWarning] {
929 &self.0
930 }
931 }