1use url::Url;
4
5#[derive(Clone, Debug, PartialEq, Eq, Default)]
7pub enum Endpoint {
8 #[default]
10 Production,
11 Custom(
13 Url,
16 ),
17}
18
19impl Endpoint {
20 pub fn base_url(&self) -> Result<Url, url::ParseError> {
37 match self {
38 Self::Production => Url::parse("https://api.figshare.com/v2/"),
39 Self::Custom(url) => Ok(normalize_base_url(url.clone())),
40 }
41 }
42}
43
44fn normalize_base_url(mut url: Url) -> Url {
45 let path = url.path().trim_end_matches('/');
46 let normalized = if path.is_empty() {
47 "/v2/".to_owned()
48 } else {
49 format!("{path}/")
50 };
51 url.set_path(&normalized);
52 url
53}
54
55#[cfg(test)]
56mod tests {
57 use super::Endpoint;
58 use url::Url;
59
60 #[test]
61 fn uses_expected_production_url() {
62 assert_eq!(
63 Endpoint::Production.base_url().unwrap().as_str(),
64 "https://api.figshare.com/v2/"
65 );
66 }
67
68 #[test]
69 fn preserves_custom_v2_url() {
70 let url = Url::parse("http://localhost:1234/v2/").unwrap();
71 assert_eq!(Endpoint::Custom(url.clone()).base_url().unwrap(), url);
72 }
73
74 #[test]
75 fn normalizes_custom_url_without_trailing_slash() {
76 let normalized = Endpoint::Custom(Url::parse("http://localhost:1234/v2").unwrap())
77 .base_url()
78 .unwrap();
79 assert_eq!(normalized.as_str(), "http://localhost:1234/v2/");
80 }
81
82 #[test]
83 fn normalizes_empty_custom_path_to_v2() {
84 let normalized = Endpoint::Custom(Url::parse("http://localhost:1234").unwrap())
85 .base_url()
86 .unwrap();
87 assert_eq!(normalized.as_str(), "http://localhost:1234/v2/");
88 }
89}