Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/published_file_service/query_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ use super::INTERFACE;
const ENDPOINT: &str = "QueryFiles";
const VERSION: &str = "1";

/// Encodes an ordered iterator into a URL array that Steam's web APIs accepts.
fn url_encode_iter<T>(name: &str, i: impl IntoIterator<Item = T>) -> String
where
T: ToString,
{
i.into_iter()
.enumerate()
.map(|(i, item)| format!("&{name}[{i}]={}", item.to_string()))
.collect::<Vec<_>>()
.concat()
}

/// Represents the query types used when querying published files on Steam Workshop.
#[derive(Debug)]
pub enum PublishedFileQueryType {
Expand Down Expand Up @@ -385,11 +397,11 @@ impl Steam {
numperpage: Option<u32>, // numperpage
creator_app_id: u32,
app_id: u32,
required_tags: &str,
excluded_tags: &str,
required_tags: Vec<String>,
excluded_tags: Vec<String>,
match_all_tags: Option<bool>,
required_flags: &str,
omitted_flags: &str,
required_flags: Vec<String>,
omitted_flags: Vec<String>,
search_text: &str,
file_type: PublishedFileInfoMatchingFileType,
child_published_file_id: u64,
Expand Down Expand Up @@ -417,10 +429,10 @@ impl Steam {
format!("&cursor={}", cursor),
format!("&creator_appid={}", creator_app_id),
format!("&appid={}", app_id),
format!("&requiredtags={}", required_tags),
format!("&excludedtags={}", excluded_tags),
format!("&required_flags={}", required_flags),
format!("&omitted_flags={}", omitted_flags),
url_encode_iter("requiredtags", required_tags),
url_encode_iter("excludedtags", excluded_tags),
url_encode_iter("required_flags", required_flags),
url_encode_iter("omitted_flags", omitted_flags),
format!("&search_text={}", search_text),
format!("&filetype={}", file_type),
format!("&child_publishedfileid={}", child_published_file_id),
Expand Down
94 changes: 92 additions & 2 deletions tests/published_file_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use steam_rs::{
mod common;

const EXAMPLE_APP_ID: u32 = 440; // Team Fortress 2
static EXAMPLE_TAG: &str = "Capture the Flag";

#[tokio::test]
pub async fn query_files() {
Expand All @@ -20,11 +21,89 @@ pub async fn query_files() {
Some(5),
EXAMPLE_APP_ID,
EXAMPLE_APP_ID,
vec![],
vec![],
None,
vec![],
vec![],
"",
"",
PublishedFileInfoMatchingFileType::Items,
0,
7,
false,
None,
None,
"",
false,
false,
true,
true,
true,
true,
true,
true,
true,
Some(true),
10,
)
.await
.unwrap();
println!("{:?}", query);

let no_tag = query.total;
println!("Total Results: {no_tag}");

let query = steam
.query_files(
PublishedFileQueryType::RankedByVote,
0,
"*",
Some(5),
EXAMPLE_APP_ID,
EXAMPLE_APP_ID,
vec![EXAMPLE_TAG.to_string()],
vec![],
Some(true),
vec![],
vec![],
"",
PublishedFileInfoMatchingFileType::Items,
0,
7,
false,
None,
None,
"",
false,
false,
true,
true,
true,
true,
true,
true,
true,
Some(true),
10,
)
.await
.unwrap();
let with_include_tag = query.total;
println!("Includes tag '{EXAMPLE_TAG}': {with_include_tag}");

let query = steam
.query_files(
PublishedFileQueryType::RankedByVote,
0,
"*",
Some(5),
EXAMPLE_APP_ID,
EXAMPLE_APP_ID,
vec![],
vec![EXAMPLE_TAG.to_string()],
Some(true),
vec![],
vec![],
"",
PublishedFileInfoMatchingFileType::Items,
0,
Expand All @@ -47,5 +126,16 @@ pub async fn query_files() {
)
.await
.unwrap();
println!("{:?}", query);
let with_exclude_tag = query.total;
println!("Excludes tag '{EXAMPLE_TAG}': {with_exclude_tag}");

assert_ne!(
with_include_tag, with_exclude_tag,
"results should not be equal"
);
assert_eq!(
no_tag,
with_include_tag + with_exclude_tag,
"mutually exclusive results should return the complete total"
);
}
Loading