steamworks/steam/
remote_storage.rs1use crate::steam::SteamResult;
2use crate::string_ext::FromUtf8NulTruncating;
3use crate::{AppId, Client, SteamId};
4use futures::Future;
5use snafu::{ResultExt, ensure};
6use std::ffi::CString;
7use steamworks_sys as sys;
8
9#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
10pub struct UgcHandle(sys::UGCHandle_t);
11
12impl UgcHandle {
13 pub fn download_to_location(
14 self,
15 client: Client,
16 location: impl Into<Vec<u8>>,
17 priority: u32,
18 ) -> impl Future<Output = Result<DownloadUGCResult, UgcDownloadToLocationError>> + Send {
19 let location = CString::new(location.into());
20 async move {
21 let location = location.context(NulSnafu)?;
22
23 let response: sys::RemoteStorageDownloadUGCResult_t = unsafe {
24 let handle = sys::SteamAPI_ISteamRemoteStorage_UGCDownloadToLocation(
25 *client.0.remote_storage,
26 self.0,
27 location.as_ptr(),
28 priority,
29 );
30
31 client.register_for_call_result(handle).await
32 };
33
34 {
35 let result = SteamResult::from_inner(response.m_eResult);
36
37 ensure!(
38 result == SteamResult::OK,
39 UGCDownloadToLocationSnafu {
40 steam_result: result,
41 }
42 );
43 }
44
45 Ok(DownloadUGCResult {
46 app_id: response.m_nAppID.into(),
47 size_in_bytes: response.m_nSizeInBytes,
48 filename: String::from_utf8_nul_truncating(&response.m_pchFileName[..]).expect(
49 "Filename returned in RemoteStorageDownloadUGCResult_t was not valid UTF-8",
50 ),
51 steam_id_owner: SteamId::new(response.m_ulSteamIDOwner),
52 })
53 }
54 }
55
56 pub(crate) fn from_inner(handle: sys::UGCHandle_t) -> Option<Self> {
57 if handle == sys::k_UGCHandleInvalid {
58 None
59 } else {
60 Some(UgcHandle(handle))
61 }
62 }
63}
64
65#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
66pub struct DownloadUGCResult {
67 app_id: AppId,
68 size_in_bytes: i32,
69 filename: String,
70 steam_id_owner: SteamId,
71}
72
73#[derive(Debug, snafu::Snafu)]
74pub enum UgcDownloadToLocationError {
75 #[snafu(display("The location provided contained nul byte(s): {}", source))]
77 Nul { source: std::ffi::NulError },
78
79 #[snafu(display("UGCDownloadToLocation() failed: {}", steam_result))]
81 UGCDownloadToLocation { steam_result: SteamResult },
82}