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
//! Endpoint selection for production or custom Figshare deployments.
use url::Url;
/// Base API endpoint used by the client.
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub enum Endpoint {
/// The public Figshare production service.
#[default]
Production,
/// A fully custom Figshare-compatible API base URL.
Custom(
/// Deployment root or base API URL, normalized to end in `/v2/` when
/// no path is supplied.
Url,
),
}
impl Endpoint {
/// Returns the API base URL for this endpoint.
///
/// # Errors
///
/// Returns an error if the configured URL cannot be parsed into a valid
/// base URL.
///
/// # Examples
///
/// ```
/// use figshare_rs::Endpoint;
///
/// let endpoint = Endpoint::Custom("http://localhost:1234".parse()?);
/// assert_eq!(endpoint.base_url()?.as_str(), "http://localhost:1234/v2/");
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn base_url(&self) -> Result<Url, url::ParseError> {
match self {
Self::Production => Url::parse("https://api.figshare.com/v2/"),
Self::Custom(url) => Ok(normalize_base_url(url.clone())),
}
}
}
fn normalize_base_url(mut url: Url) -> Url {
let path = url.path().trim_end_matches('/');
let normalized = if path.is_empty() {
"/v2/".to_owned()
} else {
format!("{path}/")
};
url.set_path(&normalized);
url
}
#[cfg(test)]
mod tests {
use super::Endpoint;
use url::Url;
#[test]
fn uses_expected_production_url() {
assert_eq!(
Endpoint::Production.base_url().unwrap().as_str(),
"https://api.figshare.com/v2/"
);
}
#[test]
fn preserves_custom_v2_url() {
let url = Url::parse("http://localhost:1234/v2/").unwrap();
assert_eq!(Endpoint::Custom(url.clone()).base_url().unwrap(), url);
}
#[test]
fn normalizes_custom_url_without_trailing_slash() {
let normalized = Endpoint::Custom(Url::parse("http://localhost:1234/v2").unwrap())
.base_url()
.unwrap();
assert_eq!(normalized.as_str(), "http://localhost:1234/v2/");
}
#[test]
fn normalizes_empty_custom_path_to_v2() {
let normalized = Endpoint::Custom(Url::parse("http://localhost:1234").unwrap())
.base_url()
.unwrap();
assert_eq!(normalized.as_str(), "http://localhost:1234/v2/");
}
}