1+ //! Fundamental types and traits for sources of Cargo packages.
2+ //!
3+ //! A source is a provider that contains source files and metadata of packages.
4+ //! It provides a number of methods to fetch those package informations, for
5+ //! example, querying metadata or downloading files for a package. These
6+ //! informations then can be used as dependencies for other Cargo packages.
7+ //!
8+ //! Notably, this module contains
9+ //!
10+ //! * [`Source`] trait as an abstraction of different sources
11+ //! * [`SourceMap`] struct as a map of all available sources
12+ //! * [`SourceId`] struct as an unique identifier for a certain source
13+ //!
14+ //! For implementations of `Source` trait, see [`crate::sources`].
15+
116use std:: collections:: hash_map:: HashMap ;
217use std:: fmt;
318use std:: task:: Poll ;
@@ -10,32 +25,53 @@ mod source_id;
1025
1126pub use self :: source_id:: { GitReference , SourceId } ;
1227
13- /// Something that finds and downloads remote packages based on names and versions.
28+ /// An abstraction of different sources of Cargo packages.
29+ ///
30+ /// The [`Source`] trait generalizes the API to interact with these providers.
31+ /// For example,
32+ ///
33+ /// * [`Source::query`] is for querying package metadata on a given
34+ /// [`Dependency`] requested by a Cargo manifest.
35+ /// * [`Source::download`] is for fetching the full package information on
36+ /// given names and versions.
37+ /// * [`Source::source_id`] is for defining an unique identifier of a source to
38+ /// distinguish one source from another, keeping Cargo safe from [dependency
39+ /// confusion attack].
40+ ///
41+ /// Normally, developers don't need to implement their own [`Source`]s. Cargo
42+ /// provides several kinds of sources implementations that should cover almost
43+ /// all use cases. See [`crate::sources`] for implementations provided by Cargo.
44+ ///
45+ /// [dependency confusion attack]: https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610
1446pub trait Source {
15- /// Returns the `SourceId` corresponding to this source.
47+ /// Returns the [ `SourceId`] corresponding to this source.
1648 fn source_id ( & self ) -> SourceId ;
1749
18- /// Returns the replaced `SourceId` corresponding to this source.
50+ /// Returns the replaced [ `SourceId`] corresponding to this source.
1951 fn replaced_source_id ( & self ) -> SourceId {
2052 self . source_id ( )
2153 }
2254
23- /// Returns whether or not this source will return summaries with
55+ /// Returns whether or not this source will return [`Summary`] items with
2456 /// checksums listed.
2557 fn supports_checksums ( & self ) -> bool ;
2658
27- /// Returns whether or not this source will return summaries with
28- /// the `precise` field in the source id listed.
59+ /// Returns whether or not this source will return [`Summary`] items with
60+ /// the `precise` field in the [`SourceId`] listed.
2961 fn requires_precise ( & self ) -> bool ;
3062
3163 /// Attempts to find the packages that match a dependency request.
64+ ///
65+ /// The `f` argument is expected to get called when any [`Summary`] becomes available.
3266 fn query (
3367 & mut self ,
3468 dep : & Dependency ,
3569 kind : QueryKind ,
3670 f : & mut dyn FnMut ( Summary ) ,
3771 ) -> Poll < CargoResult < ( ) > > ;
3872
73+ /// A helper function that collects and returns the result from
74+ /// [`Source::query`] as a list of [`Summary`] items when available.
3975 fn query_vec ( & mut self , dep : & Dependency , kind : QueryKind ) -> Poll < CargoResult < Vec < Summary > > > {
4076 let mut ret = Vec :: new ( ) ;
4177 self . query ( dep, kind, & mut |s| ret. push ( s) ) . map_ok ( |_| ret)
@@ -50,6 +86,7 @@ pub trait Source {
5086 /// Fetches the full package for each name and version specified.
5187 fn download ( & mut self , package : PackageId ) -> CargoResult < MaybePackage > ;
5288
89+ /// Fetches the full package **immediately** for each name and version specified.
5390 fn download_now ( self : Box < Self > , package : PackageId , config : & Config ) -> CargoResult < Package >
5491 where
5592 Self : std:: marker:: Sized ,
@@ -61,7 +98,8 @@ pub trait Source {
6198 Ok ( Package :: clone ( pkg) )
6299 }
63100
64- fn finish_download ( & mut self , package : PackageId , contents : Vec < u8 > ) -> CargoResult < Package > ;
101+ /// Finalizes the download contents of the given [`PackageId`] to a [`Package`].
102+ fn finish_download ( & mut self , pkg_id : PackageId , contents : Vec < u8 > ) -> CargoResult < Package > ;
65103
66104 /// Generates a unique string which represents the fingerprint of the
67105 /// current state of the source.
@@ -103,56 +141,67 @@ pub trait Source {
103141 /// as yanked. This ignores the yanked whitelist.
104142 fn is_yanked ( & mut self , _pkg : PackageId ) -> Poll < CargoResult < bool > > ;
105143
106- /// Block until all outstanding Poll::Pending requests are `Poll::Ready`.
144+ /// Block until all outstanding [` Poll::Pending`] requests are [ `Poll::Ready`] .
107145 ///
108146 /// After calling this function, the source should return `Poll::Ready` for
109147 /// any queries that previously returned `Poll::Pending`.
110148 ///
111- /// If no queries previously returned `Poll::Pending`, and ` invalidate_cache`
149+ /// If no queries previously returned `Poll::Pending`, and [`Source:: invalidate_cache`]
112150 /// was not called, this function should be a no-op.
113151 fn block_until_ready ( & mut self ) -> CargoResult < ( ) > ;
114152}
115153
154+ /// Defines how a dependency query will be performed for a [`Source`].
116155#[ derive( Copy , Clone , PartialEq , Eq ) ]
117156pub enum QueryKind {
157+ /// A query for packages exactly matching the given dependency requirement.
158+ ///
159+ /// Each source gets to define what `exact` means for it.
118160 Exact ,
161+ /// A query for packages close to the given dependency requirement.
162+ ///
119163 /// Each source gets to define what `close` means for it.
164+ ///
120165 /// Path/Git sources may return all dependencies that are at that URI,
121- /// whereas an `Index` source may return dependencies that have the same canonicalization.
166+ /// whereas an `Registry` source may return dependencies that have the same
167+ /// canonicalization.
122168 Fuzzy ,
123169}
124170
171+ /// A download status that represents if a [`Package`] has already been
172+ /// downloaded, or if not then a location to download.
125173pub enum MaybePackage {
174+ /// The [`Package`] is already downloaded.
126175 Ready ( Package ) ,
176+ /// Not yet downloaded. Here is the URL to download the [`Package`] from.
127177 Download {
178+ /// URL to download the content.
128179 url : String ,
180+ /// Text to display to the user of what is being downloaded.
129181 descriptor : String ,
182+ /// Authorization data that may be required to attach when downloading.
130183 authorization : Option < String > ,
131184 } ,
132185}
133186
187+ /// A blanket implementation forwards all methods to [`Source`].
134188impl < ' a , T : Source + ?Sized + ' a > Source for Box < T > {
135- /// Forwards to `Source::source_id`.
136189 fn source_id ( & self ) -> SourceId {
137190 ( * * self ) . source_id ( )
138191 }
139192
140- /// Forwards to `Source::replaced_source_id`.
141193 fn replaced_source_id ( & self ) -> SourceId {
142194 ( * * self ) . replaced_source_id ( )
143195 }
144196
145- /// Forwards to `Source::supports_checksums`.
146197 fn supports_checksums ( & self ) -> bool {
147198 ( * * self ) . supports_checksums ( )
148199 }
149200
150- /// Forwards to `Source::requires_precise`.
151201 fn requires_precise ( & self ) -> bool {
152202 ( * * self ) . requires_precise ( )
153203 }
154204
155- /// Forwards to `Source::query`.
156205 fn query (
157206 & mut self ,
158207 dep : & Dependency ,
@@ -170,7 +219,6 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
170219 ( * * self ) . set_quiet ( quiet)
171220 }
172221
173- /// Forwards to `Source::download`.
174222 fn download ( & mut self , id : PackageId ) -> CargoResult < MaybePackage > {
175223 ( * * self ) . download ( id)
176224 }
@@ -179,12 +227,10 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
179227 ( * * self ) . finish_download ( id, data)
180228 }
181229
182- /// Forwards to `Source::fingerprint`.
183230 fn fingerprint ( & self , pkg : & Package ) -> CargoResult < String > {
184231 ( * * self ) . fingerprint ( pkg)
185232 }
186233
187- /// Forwards to `Source::verify`.
188234 fn verify ( & self , pkg : PackageId ) -> CargoResult < ( ) > {
189235 ( * * self ) . verify ( pkg)
190236 }
@@ -210,6 +256,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
210256 }
211257}
212258
259+ /// A blanket implementation forwards all methods to [`Source`].
213260impl < ' a , T : Source + ?Sized + ' a > Source for & ' a mut T {
214261 fn source_id ( & self ) -> SourceId {
215262 ( * * self ) . source_id ( )
@@ -281,7 +328,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
281328 }
282329}
283330
284- /// A `HashMap` of `SourceId` -> `Box<Source>`.
331+ /// A [ `HashMap`] of [ `SourceId`] to `Box<Source>`.
285332#[ derive( Default ) ]
286333pub struct SourceMap < ' src > {
287334 map : HashMap < SourceId , Box < dyn Source + ' src > > ,
@@ -313,7 +360,7 @@ impl<'src> SourceMap<'src> {
313360 self . map . get_mut ( & id) . map ( |s| s. as_mut ( ) )
314361 }
315362
316- /// Like `HashMap::insert`, but derives the `SourceId` key from the `Source`.
363+ /// Like `HashMap::insert`, but derives the [ `SourceId`] key from the [ `Source`] .
317364 pub fn insert ( & mut self , source : Box < dyn Source + ' src > ) {
318365 let id = source. source_id ( ) ;
319366 self . map . insert ( id, source) ;
0 commit comments