cargo/sources/
replaced.rs

1use crate::core::source::MaybePackage;
2use crate::core::{Dependency, Package, PackageId, Source, SourceId, Summary};
3use crate::util::errors::{CargoResult, CargoResultExt};
4
5pub struct ReplacedSource<'cfg> {
6    to_replace: SourceId,
7    replace_with: SourceId,
8    inner: Box<dyn Source + 'cfg>,
9}
10
11impl<'cfg> ReplacedSource<'cfg> {
12    pub fn new(
13        to_replace: SourceId,
14        replace_with: SourceId,
15        src: Box<dyn Source + 'cfg>,
16    ) -> ReplacedSource<'cfg> {
17        ReplacedSource {
18            to_replace,
19            replace_with,
20            inner: src,
21        }
22    }
23}
24
25impl<'cfg> Source for ReplacedSource<'cfg> {
26    fn source_id(&self) -> SourceId {
27        self.to_replace
28    }
29
30    fn replaced_source_id(&self) -> SourceId {
31        self.replace_with
32    }
33
34    fn supports_checksums(&self) -> bool {
35        self.inner.supports_checksums()
36    }
37
38    fn requires_precise(&self) -> bool {
39        self.inner.requires_precise()
40    }
41
42    fn query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> {
43        let (replace_with, to_replace) = (self.replace_with, self.to_replace);
44        let dep = dep.clone().map_source(to_replace, replace_with);
45
46        self.inner
47            .query(&dep, &mut |summary| {
48                f(summary.map_source(replace_with, to_replace))
49            })
50            .chain_err(|| format!("failed to query replaced source {}", self.to_replace))?;
51        Ok(())
52    }
53
54    fn fuzzy_query(&mut self, dep: &Dependency, f: &mut dyn FnMut(Summary)) -> CargoResult<()> {
55        let (replace_with, to_replace) = (self.replace_with, self.to_replace);
56        let dep = dep.clone().map_source(to_replace, replace_with);
57
58        self.inner
59            .fuzzy_query(&dep, &mut |summary| {
60                f(summary.map_source(replace_with, to_replace))
61            })
62            .chain_err(|| format!("failed to query replaced source {}", self.to_replace))?;
63        Ok(())
64    }
65
66    fn update(&mut self) -> CargoResult<()> {
67        self.inner
68            .update()
69            .chain_err(|| format!("failed to update replaced source {}", self.to_replace))?;
70        Ok(())
71    }
72
73    fn download(&mut self, id: PackageId) -> CargoResult<MaybePackage> {
74        let id = id.with_source_id(self.replace_with);
75        let pkg = self
76            .inner
77            .download(id)
78            .chain_err(|| format!("failed to download replaced source {}", self.to_replace))?;
79        Ok(match pkg {
80            MaybePackage::Ready(pkg) => {
81                MaybePackage::Ready(pkg.map_source(self.replace_with, self.to_replace))
82            }
83            other @ MaybePackage::Download { .. } => other,
84        })
85    }
86
87    fn finish_download(&mut self, id: PackageId, data: Vec<u8>) -> CargoResult<Package> {
88        let id = id.with_source_id(self.replace_with);
89        let pkg = self
90            .inner
91            .finish_download(id, data)
92            .chain_err(|| format!("failed to download replaced source {}", self.to_replace))?;
93        Ok(pkg.map_source(self.replace_with, self.to_replace))
94    }
95
96    fn fingerprint(&self, id: &Package) -> CargoResult<String> {
97        self.inner.fingerprint(id)
98    }
99
100    fn verify(&self, id: PackageId) -> CargoResult<()> {
101        let id = id.with_source_id(self.replace_with);
102        self.inner.verify(id)
103    }
104
105    fn describe(&self) -> String {
106        format!(
107            "{} (which is replacing {})",
108            self.inner.describe(),
109            self.to_replace
110        )
111    }
112
113    fn is_replaced(&self) -> bool {
114        true
115    }
116
117    fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) {
118        let pkgs = pkgs
119            .iter()
120            .map(|id| id.with_source_id(self.replace_with))
121            .collect::<Vec<_>>();
122        self.inner.add_to_yanked_whitelist(&pkgs);
123    }
124
125    fn is_yanked(&mut self, pkg: PackageId) -> CargoResult<bool> {
126        self.inner.is_yanked(pkg)
127    }
128}