XC Api post reuqest support (#661)

* XC Api post reuqest support
This commit is contained in:
euzu
2026-03-22 19:55:14 +01:00
committed by GitHub
parent 90193d7260
commit 65b774dee3
5 changed files with 400 additions and 50 deletions
+133 -1
View File
@@ -1,4 +1,4 @@
#[derive(Debug, serde::Serialize, serde::Deserialize, Default)]
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, Default)]
pub struct UserApiRequest {
#[serde(default)]
pub username: String,
@@ -31,6 +31,37 @@ pub struct UserApiRequest {
}
impl UserApiRequest {
pub fn merge_prefer_primary(primary: &Self, fallback: &Self) -> Self {
fn pick(primary: &str, fallback: &str) -> String {
if primary.trim().is_empty() {
fallback.to_string()
} else {
primary.to_string()
}
}
Self {
username: pick(&primary.username, &fallback.username),
password: pick(&primary.password, &fallback.password),
token: pick(&primary.token, &fallback.token),
action: pick(&primary.action, &fallback.action),
series_id: pick(&primary.series_id, &fallback.series_id),
vod_id: pick(&primary.vod_id, &fallback.vod_id),
stream_id: pick(&primary.stream_id, &fallback.stream_id),
category_id: pick(&primary.category_id, &fallback.category_id),
limit: pick(&primary.limit, &fallback.limit),
start: pick(&primary.start, &fallback.start),
end: pick(&primary.end, &fallback.end),
stream: pick(&primary.stream, &fallback.stream),
duration: pick(&primary.duration, &fallback.duration),
content_type: pick(&primary.content_type, &fallback.content_type),
}
}
pub fn merge_query_over_form(query: &Self, form: Option<&Self>) -> Self {
form.map_or_else(|| query.clone(), |form_req| Self::merge_prefer_primary(query, form_req))
}
pub fn get_limit(&self) -> u32 {
if self.limit.is_empty() {
0
@@ -39,3 +70,104 @@ impl UserApiRequest {
}
}
}
#[cfg(test)]
mod tests {
use super::UserApiRequest;
#[test]
fn merge_prefer_primary_uses_fallback_for_empty_fields() {
let primary = UserApiRequest {
username: String::new(),
password: String::new(),
action: String::from("get_live_categories"),
..UserApiRequest::default()
};
let fallback = UserApiRequest {
username: String::from("xtr"),
password: String::from("xtr"),
..UserApiRequest::default()
};
let merged = UserApiRequest::merge_prefer_primary(&primary, &fallback);
assert_eq!(merged.username, "xtr");
assert_eq!(merged.password, "xtr");
assert_eq!(merged.action, "get_live_categories");
}
#[test]
fn merge_prefer_primary_uses_fallback_for_whitespace_only_fields() {
let primary = UserApiRequest {
username: String::from(" "),
password: String::from("\t"),
token: String::from("\n"),
action: String::from(" "),
series_id: String::from(" "),
vod_id: String::from(" "),
stream_id: String::from(" "),
category_id: String::from(" "),
limit: String::from(" "),
start: String::from(" "),
end: String::from(" "),
stream: String::from(" "),
duration: String::from(" "),
content_type: String::from(" "),
};
let fallback = UserApiRequest {
username: String::from("user"),
password: String::from("pass"),
token: String::from("token"),
action: String::from("action"),
series_id: String::from("series"),
vod_id: String::from("vod"),
stream_id: String::from("stream"),
category_id: String::from("category"),
limit: String::from("10"),
start: String::from("100"),
end: String::from("200"),
stream: String::from("300"),
duration: String::from("60"),
content_type: String::from("m3u_plus"),
};
let merged = UserApiRequest::merge_prefer_primary(&primary, &fallback);
assert_eq!(merged.username, "user");
assert_eq!(merged.password, "pass");
assert_eq!(merged.token, "token");
assert_eq!(merged.action, "action");
assert_eq!(merged.series_id, "series");
assert_eq!(merged.vod_id, "vod");
assert_eq!(merged.stream_id, "stream");
assert_eq!(merged.category_id, "category");
assert_eq!(merged.limit, "10");
assert_eq!(merged.start, "100");
assert_eq!(merged.end, "200");
assert_eq!(merged.stream, "300");
assert_eq!(merged.duration, "60");
assert_eq!(merged.content_type, "m3u_plus");
}
#[test]
fn merge_query_over_form_prefers_query_fields() {
let query = UserApiRequest {
username: String::from("query-user"),
token: String::from("query-token"),
action: String::from("query-action"),
..UserApiRequest::default()
};
let form = UserApiRequest {
username: String::from("form-user"),
token: String::from("form-token"),
action: String::from("form-action"),
..UserApiRequest::default()
};
let merged = UserApiRequest::merge_query_over_form(&query, Some(&form));
assert_eq!(merged.username, "query-user");
assert_eq!(merged.token, "query-token");
assert_eq!(merged.action, "query-action");
}
}