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,30 +141,45 @@ 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}
@@ -281,7 +334,7 @@ impl<'a, T: Source + ?Sized + 'a> Source for &'a mut T {
281334 }
282335}
283336
284- /// A `HashMap` of `SourceId` -> `Box<Source>`.
337+ /// A [ `HashMap`] of [ `SourceId`] to `Box<Source>`.
285338#[ derive( Default ) ]
286339pub struct SourceMap < ' src > {
287340 map : HashMap < SourceId , Box < dyn Source + ' src > > ,
@@ -313,7 +366,7 @@ impl<'src> SourceMap<'src> {
313366 self . map . get_mut ( & id) . map ( |s| s. as_mut ( ) )
314367 }
315368
316- /// Like `HashMap::insert`, but derives the `SourceId` key from the `Source`.
369+ /// Like `HashMap::insert`, but derives the [ `SourceId`] key from the [ `Source`] .
317370 pub fn insert ( & mut self , source : Box < dyn Source + ' src > ) {
318371 let id = source. source_id ( ) ;
319372 self . map . insert ( id, source) ;
0 commit comments