cargo/sources/
replaced.rs
1use crate::core::{Dependency, Package, PackageId, SourceId};
2use crate::sources::source::MaybePackage;
3use crate::sources::source::QueryKind;
4use crate::sources::source::Source;
5use crate::sources::IndexSummary;
6use crate::util::errors::CargoResult;
7use std::task::Poll;
8
9pub struct ReplacedSource<'gctx> {
16 to_replace: SourceId,
18 replace_with: SourceId,
20 inner: Box<dyn Source + 'gctx>,
21}
22
23impl<'gctx> ReplacedSource<'gctx> {
24 pub fn new(
28 to_replace: SourceId,
29 replace_with: SourceId,
30 src: Box<dyn Source + 'gctx>,
31 ) -> ReplacedSource<'gctx> {
32 ReplacedSource {
33 to_replace,
34 replace_with,
35 inner: src,
36 }
37 }
38
39 fn is_builtin_replacement(&self) -> bool {
44 self.replace_with.is_crates_io() && self.to_replace.is_crates_io()
45 }
46}
47
48impl<'gctx> Source for ReplacedSource<'gctx> {
49 fn source_id(&self) -> SourceId {
50 self.to_replace
51 }
52
53 fn replaced_source_id(&self) -> SourceId {
54 self.replace_with
55 }
56
57 fn supports_checksums(&self) -> bool {
58 self.inner.supports_checksums()
59 }
60
61 fn requires_precise(&self) -> bool {
62 self.inner.requires_precise()
63 }
64
65 fn query(
66 &mut self,
67 dep: &Dependency,
68 kind: QueryKind,
69 f: &mut dyn FnMut(IndexSummary),
70 ) -> Poll<CargoResult<()>> {
71 let (replace_with, to_replace) = (self.replace_with, self.to_replace);
72 let dep = dep.clone().map_source(to_replace, replace_with);
73
74 self.inner
75 .query(&dep, kind, &mut |summary| {
76 f(summary.map_summary(|s| s.map_source(replace_with, to_replace)))
77 })
78 .map_err(|e| {
79 if self.is_builtin_replacement() {
80 e
81 } else {
82 e.context(format!(
83 "failed to query replaced source {}",
84 self.to_replace
85 ))
86 }
87 })
88 }
89
90 fn invalidate_cache(&mut self) {
91 self.inner.invalidate_cache()
92 }
93
94 fn set_quiet(&mut self, quiet: bool) {
95 self.inner.set_quiet(quiet);
96 }
97
98 fn download(&mut self, id: PackageId) -> CargoResult<MaybePackage> {
99 let id = id.with_source_id(self.replace_with);
100 let pkg = self.inner.download(id).map_err(|e| {
101 if self.is_builtin_replacement() {
102 e
103 } else {
104 e.context(format!(
105 "failed to download replaced source {}",
106 self.to_replace
107 ))
108 }
109 })?;
110 Ok(match pkg {
111 MaybePackage::Ready(pkg) => {
112 MaybePackage::Ready(pkg.map_source(self.replace_with, self.to_replace))
113 }
114 other @ MaybePackage::Download { .. } => other,
115 })
116 }
117
118 fn finish_download(&mut self, id: PackageId, data: Vec<u8>) -> CargoResult<Package> {
119 let id = id.with_source_id(self.replace_with);
120 let pkg = self.inner.finish_download(id, data).map_err(|e| {
121 if self.is_builtin_replacement() {
122 e
123 } else {
124 e.context(format!(
125 "failed to download replaced source {}",
126 self.to_replace
127 ))
128 }
129 })?;
130 Ok(pkg.map_source(self.replace_with, self.to_replace))
131 }
132
133 fn fingerprint(&self, id: &Package) -> CargoResult<String> {
134 self.inner.fingerprint(id)
135 }
136
137 fn verify(&self, id: PackageId) -> CargoResult<()> {
138 let id = id.with_source_id(self.replace_with);
139 self.inner.verify(id)
140 }
141
142 fn describe(&self) -> String {
143 if self.is_builtin_replacement() {
144 self.inner.describe()
145 } else {
146 format!(
147 "{} (which is replacing {})",
148 self.inner.describe(),
149 self.to_replace
150 )
151 }
152 }
153
154 fn is_replaced(&self) -> bool {
155 !self.is_builtin_replacement()
156 }
157
158 fn add_to_yanked_whitelist(&mut self, pkgs: &[PackageId]) {
159 let pkgs = pkgs
160 .iter()
161 .map(|id| id.with_source_id(self.replace_with))
162 .collect::<Vec<_>>();
163 self.inner.add_to_yanked_whitelist(&pkgs);
164 }
165
166 fn is_yanked(&mut self, pkg: PackageId) -> Poll<CargoResult<bool>> {
167 self.inner.is_yanked(pkg)
168 }
169
170 fn block_until_ready(&mut self) -> CargoResult<()> {
171 self.inner.block_until_ready().map_err(|e| {
172 if self.is_builtin_replacement() {
173 e
174 } else {
175 e.context(format!(
176 "failed to update replaced source {}",
177 self.to_replace
178 ))
179 }
180 })
181 }
182}