lychee_lib/types/basic_auth/
selector.rs1use std::str::FromStr;
2
3use serde_with::DeserializeFromStr;
4use thiserror::Error;
5
6use crate::{BasicAuthCredentials, types::basic_auth::BasicAuthCredentialsParseError};
7
8#[derive(Clone, Debug, Error, PartialEq)]
9pub enum BasicAuthSelectorParseError {
10 #[error("Empty selector input")]
11 EmptyInput,
12
13 #[error("Missing basic auth credentials or URI. Valid form is '<uri> <username>:<password>'")]
14 InvalidSyntax,
15
16 #[error(
17 "Too many space separated values. Expected 2, got {0}. Valid form is '<uri> <username>:<password>'"
18 )]
19 TooManyParts(usize),
20
21 #[error("Basic auth credentials error")]
22 BasicAuthCredentialsParseError(#[from] BasicAuthCredentialsParseError),
23
24 #[error("Regex compile error")]
25 RegexError(#[from] regex::Error),
26}
27
28#[derive(Debug, Clone, DeserializeFromStr, PartialEq)]
32pub struct BasicAuthSelector {
33 pub credentials: BasicAuthCredentials,
35
36 pub raw_uri_regex: String,
38}
39
40impl FromStr for BasicAuthSelector {
41 type Err = BasicAuthSelectorParseError;
42
43 fn from_str(selector: &str) -> Result<Self, Self::Err> {
44 let selector = selector.trim();
45
46 if selector.is_empty() {
47 return Err(BasicAuthSelectorParseError::EmptyInput);
48 }
49
50 let parts: Vec<_> = selector.split(' ').collect();
51
52 if parts.len() <= 1 {
53 return Err(BasicAuthSelectorParseError::InvalidSyntax);
54 }
55
56 if parts.len() > 2 {
57 return Err(BasicAuthSelectorParseError::TooManyParts(parts.len()));
58 }
59
60 Ok(Self {
61 credentials: parts[1].parse()?,
62 raw_uri_regex: parts[0].to_string(),
63 })
64 }
65}
66
67#[cfg(test)]
68mod test {
69 use super::*;
70
71 #[test]
72 fn test_valid_basic_auth_selector() {
73 let input = "http://example.com foo:bar";
74 let selector: BasicAuthSelector = input.parse().unwrap();
75
76 assert_eq!(selector.raw_uri_regex, "http://example.com".to_string());
77 assert_eq!(
78 selector.credentials,
79 BasicAuthCredentials {
80 username: "foo".to_string(),
81 password: "bar".to_string()
82 }
83 );
84 }
85
86 #[test]
87 fn test_missing_uri_basic_auth_selector() {
88 let input = "foo:bar";
89 let result = BasicAuthSelector::from_str(input);
90
91 assert!(result.is_err());
92 assert_eq!(
93 result.unwrap_err(),
94 BasicAuthSelectorParseError::InvalidSyntax
95 );
96 }
97
98 #[test]
99 fn test_missing_credentials_basic_auth_selector() {
100 let input = "https://example.com";
101 let result = BasicAuthSelector::from_str(input);
102
103 assert!(result.is_err());
104 assert_eq!(
105 result.unwrap_err(),
106 BasicAuthSelectorParseError::InvalidSyntax
107 );
108 }
109
110 #[test]
111 fn test_empty_basic_auth_selector() {
112 let input = "";
113 let result = BasicAuthSelector::from_str(input);
114
115 assert!(result.is_err());
116 assert_eq!(result.unwrap_err(), BasicAuthSelectorParseError::EmptyInput);
117
118 let input = " ";
119 let result = BasicAuthSelector::from_str(input);
120
121 assert!(result.is_err());
122 assert_eq!(result.unwrap_err(), BasicAuthSelectorParseError::EmptyInput);
123 }
124
125 #[test]
126 fn test_too_many_parts_basic_auth_selector() {
127 let input = "";
128 let result = BasicAuthSelector::from_str(input);
129
130 assert!(result.is_err());
131 assert_eq!(result.unwrap_err(), BasicAuthSelectorParseError::EmptyInput);
132
133 let input = " ";
134 let result = BasicAuthSelector::from_str(input);
135
136 assert!(result.is_err());
137 assert_eq!(result.unwrap_err(), BasicAuthSelectorParseError::EmptyInput);
138 }
139}