1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
mod args;
mod client;
mod features;
mod printer;
mod registry;
mod util;
#[doc(inline)]
pub use client::Client;
#[doc(inline)]
pub use registry::{Crate, Registry, YankState};
#[doc(inline)]
pub use args::{Args, PkgId};
#[doc(inline)]
pub use printer::*;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum OfflineError {
List,
Latest,
CacheMiss,
}
impl OfflineError {
pub fn to_error(&self) -> anyhow::Error {
let err = match self {
Self::List => {
"must be able to connect to https://crates.io to list versions"
}
Self::Latest =>{
"must be able to connect to https://crates.io to get the latest version"
} ,
Self::CacheMiss => {
"crate not found in local registry or cache. must be able to connect to https://crates.io to fetch it"
},
};
anyhow::anyhow!(err)
}
}
#[derive(Debug)]
pub enum Lookup {
Partial {
name: String,
version: String,
},
Workspace(features::Workspace),
}
pub fn lookup(pkg_id: &PkgId, client: &Option<Client>) -> anyhow::Result<Lookup> {
match pkg_id {
PkgId::Remote {
name,
semver: Some(semver),
} => Ok(Lookup::Partial {
name: name.clone(),
version: semver.clone(),
}),
PkgId::Remote { name, .. } => {
let client = client
.as_ref()
.ok_or_else(|| OfflineError::Latest.to_error())?;
let pkg = client.get_latest(name).map_err(|_| cannot_find(pkg_id))?;
Ok(Lookup::Partial {
name: pkg.name,
version: pkg.version,
})
}
PkgId::Local(path) => Crate::from_path(path).map(Lookup::Workspace),
}
}
fn cannot_find(pkg_id: &PkgId) -> anyhow::Error {
anyhow::anyhow!(
"cannot find a crate matching '{}'. maybe the latest version was yanked?",
pkg_id
)
}