Skip to content

Commit 0ac1e90

Browse files
committed
Add memory segment APIs
1 parent ff70af3 commit 0ac1e90

File tree

7 files changed

+230
-1
lines changed

7 files changed

+230
-1
lines changed

Diff for: Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ num = { version = "0.2", default-features = false }
5757
sync = ["tokio", "hyper-tls"]
5858
protocol-docs = []
5959
default = ["sync"]
60+
# enables tests which modify game state (temporarily, but still)
61+
destructive-tests = []
6062

6163
[dev-dependencies]
6264
# .env parsing

Diff for: src/endpoints/memory_segment.rs

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//! Interpreting memory calls.
2+
use crate::{
3+
data,
4+
error::{ApiError, Result},
5+
EndpointResult,
6+
};
7+
8+
/// Call raw result.
9+
#[derive(serde_derive::Deserialize, Clone, Hash, Debug)]
10+
#[doc(hidden)]
11+
pub(crate) struct Response {
12+
ok: i32,
13+
data: String,
14+
}
15+
16+
/// Memory segment retrieval result
17+
#[derive(Clone, Hash, Debug)]
18+
pub(crate) struct MemorySegment {
19+
pub data: String,
20+
/// Phantom data in order to allow adding any additional fields in the future.
21+
_non_exhaustive: (),
22+
}
23+
24+
impl EndpointResult for MemorySegment {
25+
type RequestResult = Response;
26+
type ErrorResult = data::ApiError;
27+
28+
fn from_raw(raw: Response) -> Result<Self> {
29+
let Response { ok, data } = raw;
30+
31+
if ok != 1 {
32+
return Err(ApiError::NotOk(ok).into());
33+
}
34+
35+
Ok(MemorySegment {
36+
data,
37+
_non_exhaustive: (),
38+
})
39+
}
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::*;
45+
use crate::EndpointResult;
46+
use serde_json;
47+
48+
fn test_parse(json: serde_json::Value) {
49+
let response = serde_json::from_value(json).unwrap();
50+
51+
let _ = MemorySegment::from_raw(response).unwrap();
52+
}
53+
54+
#[test]
55+
fn parse_sample() {
56+
test_parse(json! ({
57+
"ok": 1,
58+
"data": "asdf"
59+
}));
60+
}
61+
}

Diff for: src/endpoints/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44
mod leaderboard;
55
mod login;
66
mod map_stats;
7+
mod memory_segment;
78
mod my_info;
89
mod recent_pvp;
910
mod register;
1011
mod room_overview;
1112
mod room_status;
1213
mod room_terrain;
14+
mod set_memory_segment;
1315
mod shards;
1416
mod world_start_room;
1517

@@ -19,5 +21,8 @@ pub mod template;
1921

2022
pub use self::{
2123
leaderboard::*, login::*, map_stats::*, my_info::*, recent_pvp::*, register::*,
22-
room_overview::*, room_status::*, room_terrain::*, shards::*, world_start_room::*,
24+
room_overview::*, room_status::*, room_terrain::*, set_memory_segment::*, shards::*,
25+
world_start_room::*,
2326
};
27+
28+
pub(crate) use self::memory_segment::*;

Diff for: src/endpoints/set_memory_segment.rs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! Interpreting memory calls.
2+
use std::borrow::Cow;
3+
4+
use crate::{
5+
data,
6+
error::{ApiError, Result},
7+
EndpointResult,
8+
};
9+
10+
/// Call raw result.
11+
#[derive(serde_derive::Deserialize, Clone, Hash, Debug)]
12+
#[doc(hidden)]
13+
pub(crate) struct Response {
14+
ok: i32,
15+
}
16+
17+
/// SetMemorySegment details
18+
#[derive(Serialize, Clone, Hash, Debug)]
19+
pub struct SetMemorySegmentArgs<'a> {
20+
/// The segment to set.
21+
pub segment: u32,
22+
/// The shard to set it in (optional for private servers).
23+
pub shard: Option<Cow<'a, str>>,
24+
/// The data
25+
pub data: Cow<'a, str>,
26+
}
27+
28+
/// Memory segment set result
29+
#[derive(Clone, Hash, Debug)]
30+
pub(crate) struct SetMemorySegment {
31+
/// Phantom data in order to allow adding any additional fields in the future.
32+
_non_exhaustive: (),
33+
}
34+
35+
impl EndpointResult for SetMemorySegment {
36+
type RequestResult = Response;
37+
type ErrorResult = data::ApiError;
38+
39+
fn from_raw(raw: Response) -> Result<Self> {
40+
let Response { ok } = raw;
41+
42+
if ok != 1 {
43+
return Err(ApiError::NotOk(ok).into());
44+
}
45+
46+
Ok(SetMemorySegment {
47+
_non_exhaustive: (),
48+
})
49+
}
50+
}
51+
52+
#[cfg(test)]
53+
mod tests {
54+
use super::*;
55+
use crate::EndpointResult;
56+
use serde_json;
57+
58+
fn test_parse(json: serde_json::Value) {
59+
let response = serde_json::from_value(json).unwrap();
60+
61+
let _ = SetMemorySegment::from_raw(response).unwrap();
62+
}
63+
64+
#[test]
65+
fn parse_sample() {
66+
test_parse(json! ({
67+
"ok": 1,
68+
}));
69+
}
70+
}

Diff for: src/lib.rs

+50
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,56 @@ impl<C: hyper::client::connect::Connect + 'static> Api<C> {
529529
])
530530
.send()
531531
}
532+
533+
/// Gets the player's memory segment on a given shard
534+
pub fn memory_segment<'b, U>(
535+
&self,
536+
shard: Option<U>,
537+
segment: u32,
538+
) -> Result<impl Future<Item = String, Error = Error>, NoToken>
539+
where
540+
U: Into<Cow<'b, str>>,
541+
{
542+
match shard {
543+
Some(shard) => self
544+
.get::<MemorySegment>("user/memory-segment")
545+
.params(&[
546+
("segment", segment.to_string()),
547+
("shard", shard.into().into_owned()),
548+
])
549+
.auth()
550+
.send(),
551+
None => self
552+
.get::<MemorySegment>("user/memory-segment")
553+
.params(&[("segment", segment.to_string())])
554+
.auth()
555+
.send(),
556+
}
557+
.map(|fut| fut.map(|res| res.data))
558+
}
559+
560+
/// Sets the player's memory segment on a given shard
561+
pub fn set_memory_segment<'b, U, V>(
562+
&self,
563+
shard: Option<U>,
564+
segment: u32,
565+
data: V,
566+
) -> Result<impl Future<Item = (), Error = Error>, NoToken>
567+
where
568+
U: Into<Cow<'b, str>>,
569+
V: Into<Cow<'b, str>>,
570+
{
571+
let args = SetMemorySegmentArgs {
572+
segment,
573+
shard: shard.map(Into::into),
574+
data: data.into(),
575+
};
576+
577+
self.post("user/memory-segment", args)
578+
.auth()
579+
.send()
580+
.map(|fut| fut.map(|_: SetMemorySegment| ()))
581+
}
532582
}
533583

534584
trait PartialRequestAuth<T> {

Diff for: src/sync.rs

+24
Original file line numberDiff line numberDiff line change
@@ -341,4 +341,28 @@ impl<C: hyper::client::connect::Connect + 'static> SyncApi<C> {
341341
offset,
342342
)?)
343343
}
344+
345+
/// Gets a player's memory segment
346+
pub fn memory_segment<'b, U>(&mut self, shard: Option<U>, segment: u32) -> Result<String, Error>
347+
where
348+
U: Into<Cow<'b, str>>,
349+
{
350+
self.runtime
351+
.block_on(self.client.memory_segment(shard, segment)?)
352+
}
353+
354+
/// Sets a player's memory segment
355+
pub fn set_memory_segment<'b, U, V>(
356+
&mut self,
357+
shard: Option<U>,
358+
segment: u32,
359+
data: V,
360+
) -> Result<(), Error>
361+
where
362+
U: Into<Cow<'b, str>>,
363+
V: Into<Cow<'b, str>>,
364+
{
365+
self.runtime
366+
.block_on(self.client.set_memory_segment(shard, segment, data)?)
367+
}
344368
}

Diff for: tests/authenticated_tests.rs

+17
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,20 @@ fn test_auth_leaderboard_limit_parameter_error() {
193193
}
194194
}
195195
}
196+
197+
#[test]
198+
#[cfg(feature = "destructive-tests")]
199+
fn test_memory_segment() {
200+
let mut api = logged_in();
201+
202+
let orig = api.memory_segment(Some("shard0"), 1).unwrap();
203+
204+
api.set_memory_segment(Some("shard0"), 1, "hi, you!")
205+
.unwrap();
206+
207+
let retrieved = api.memory_segment(Some("shard0"), 1).unwrap();
208+
209+
api.set_memory_segment(Some("shard0"), 1, orig).unwrap();
210+
211+
assert_eq!(&retrieved, "hi, you!");
212+
}

0 commit comments

Comments
 (0)