gitlab_time_report/fetch_api/
fetch_options.rs1use thiserror::Error;
4
5#[derive(Default, Debug, PartialEq, Clone)]
8pub struct FetchOptions {
9 pub(super) protocol: String,
11 pub(super) host: String,
13 pub(super) path: String,
15 pub(super) token: Option<String>,
17}
18
19impl FetchOptions {
20 pub fn new(url: &str, token: Option<String>) -> Result<Self, FetchOptionsError> {
36 let (protocol, host, path) =
37 Self::split_url(url).ok_or(FetchOptionsError::InvalidUrl(url.into()))?;
38 Ok(Self {
39 protocol,
40 host,
41 path,
42 token,
43 })
44 }
45
46 fn split_url(full_url: &str) -> Option<(String, String, String)> {
48 let (protocol, rest) = full_url.split_once("://").unwrap_or(("https", full_url));
50
51 let url_parts = rest.splitn(2, '/').collect::<Vec<_>>();
52
53 if url_parts.len() != 2 || !url_parts[1].contains('/') {
56 return None;
57 }
58 Some((protocol.into(), url_parts[0].into(), url_parts[1].into()))
59 }
60}
61
62#[derive(Debug, Error)]
64pub enum FetchOptionsError {
65 #[error("Invalid URL: {0}")]
66 InvalidUrl(String),
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn create_new_fetch_options() {
75 let url = "https://gitlab.ost.ch/gitlab-time-report/gitlab-time-report";
76 let token = "MyAccessToken".to_string();
77 let result = FetchOptions {
78 protocol: "https".into(),
79 host: "gitlab.ost.ch".into(),
80 path: "gitlab-time-report/gitlab-time-report".into(),
81 token: Some(token.clone()),
82 };
83
84 let output = FetchOptions::new(url, Some(token)).unwrap();
85 assert_eq!(output, result);
86 }
87
88 #[test]
89 fn create_new_fetch_options_without_protocol() {
90 let url = "gitlab.ost.ch/gitlab-time-report/gitlab-time-report";
91 let token = "MyAccessToken".to_string();
92 let result = FetchOptions {
93 protocol: "https".into(),
94 host: "gitlab.ost.ch".into(),
95 path: "gitlab-time-report/gitlab-time-report".into(),
96 token: Some(token.clone()),
97 };
98
99 let output = FetchOptions::new(url, Some(token)).unwrap();
100 assert_eq!(output, result);
101 }
102
103 #[test]
104 fn split_url_correctly() {
105 let input = "https://gitlab.ost.ch/gitlab-time-report/gitlab-time-report";
106 let result = (
107 "https".into(),
108 "gitlab.ost.ch".into(),
109 "gitlab-time-report/gitlab-time-report".into(),
110 );
111 let output = FetchOptions::split_url(input).unwrap();
112 assert_eq!(output, result);
113 }
114
115 #[test]
116 fn split_url_one_slash() {
117 let input = "https://gitlab.com/gitlab-org";
118 let output = FetchOptions::split_url(input);
119 assert!(output.is_none());
120 }
121}