1#[macro_use]
2extern crate serde_derive;
3
4#[macro_use]
5extern crate serde_json;
6
7pub mod gateway {
8 #[derive(Debug, Serialize, Deserialize, Default, PartialEq, Clone)]
12 pub struct ResourceIdentifier {
13 pub rid: String,
15 }
16
17 pub fn model_result(model: serde_json::Value) -> serde_json::Value {
19 json!({
20 "result" :{
21 "model" : model
22 }
23 })
24 }
25
26 pub fn error_not_found(msg: &str) -> serde_json::Value {
28 json!({
29 "error": {
30 "code": "system.notFound",
31 "message": msg
32 }
33 })
34 }
35
36 pub fn error_invalid_params(msg: &str) -> serde_json::Value {
38 json!({
39 "error": {
40 "code": "system.invalidParams",
41 "message": msg
42 }
43 })
44 }
45
46 pub fn success_response() -> serde_json::Value {
48 json!({ "result": null })
49 }
50
51 #[derive(Debug, Serialize, Deserialize, PartialEq)]
53 pub enum ResProtocolRequest {
54 Get(String),
55 New(String),
56 Set(String),
57 Delete(String),
58 Access(String),
59 Call(String, String),
60 Unknown,
61 }
62
63 impl ToString for ResProtocolRequest {
64 fn to_string(&self) -> String {
65 match self {
66 ResProtocolRequest::Get(resid) => format!("get.{}", resid),
67 ResProtocolRequest::New(resid) => format!("call.{}.new", resid),
68 ResProtocolRequest::Set(resid) => format!("call.{}.set", resid),
69 ResProtocolRequest::Delete(resid) => format!("call.{}.delete", resid),
70 ResProtocolRequest::Access(resid) => format!("access.{}", resid),
71 ResProtocolRequest::Call(resid, method) => format!("call.{}.{}", resid, method),
72 ResProtocolRequest::Unknown => "??".to_string(),
73 }
74 }
75 }
76
77 impl From<&str> for ResProtocolRequest {
78 fn from(source: &str) -> Self {
79 if source.starts_with("get.") {
80 ResProtocolRequest::Get(source[4..].to_string())
81 } else if source.starts_with("call.") && source.ends_with(".new") {
82 ResProtocolRequest::New(source[5..=source.len() - 5].to_string())
83 } else if source.starts_with("call.") && source.ends_with(".set") {
84 ResProtocolRequest::Set(source[5..=source.len() - 5].to_string())
85 } else if source.starts_with("access.") {
86 ResProtocolRequest::Access(source[7..].to_string())
87 } else if source.ends_with("delete") {
88 ResProtocolRequest::Delete(source[5..=source.len() - 8].to_string())
89 } else if source.starts_with("call.") {
90 let tokens: Vec<&str> = source.split('.').collect();
92 let rid = tokens[1..tokens.len() - 1].join(".");
93 let method = tokens[tokens.len() - 1];
94 ResProtocolRequest::Call(rid, method.to_string())
95 } else {
96 ResProtocolRequest::Unknown
97 }
98 }
99 }
100}
101
102pub mod timer {
103 include!(concat!(env!("OUT_DIR"), "/timer.rs"));
105
106 use prost::Message;
107
108 pub const OP_TIMER_TICK: &str = "decs:timer!Tick";
110
111 impl Into<TimerTick> for &[u8] {
112 fn into(self) -> TimerTick {
113 TimerTick::decode(self).unwrap()
114 }
115 }
116
117 #[derive(Debug, Serialize, Deserialize, Default)]
119 pub struct GameLoopTick {
120 pub seq_no: u64,
122 pub elapsed_ms: u32,
124 pub shard: String,
126 }
127
128 impl GameLoopTick {
129 pub fn from_tick(source: &TimerTick, shard: &str) -> Self {
131 GameLoopTick {
132 seq_no: source.seq_no as _,
133 elapsed_ms: source.elapsed_ms as _,
134 shard: shard.to_string(),
135 }
136 }
137 }
138}
139
140pub mod shard {
141 #[derive(Debug, Serialize, Deserialize, Default)]
145 pub struct Shard {
146 pub name: String,
148 pub capacity: u32,
150 #[serde(default)]
152 pub current: u32,
153 }
154
155 impl Shard {
156 pub fn the_void() -> Shard {
158 Shard {
159 name: "the_void".to_string(),
160 capacity: 1_000,
161 current: 0,
162 }
163 }
164 }
165}
166
167pub mod systemmgr {
168 #[derive(Debug, Serialize, Deserialize, Default)]
172 pub struct EntityFrame {
173 pub seq_no: u64,
175 pub elapsed_ms: u32,
177 pub shard: String,
179 pub entity_id: String,
181 }
182
183 #[derive(Debug, Serialize, Deserialize, Default)]
185 pub struct System {
186 pub name: String,
188 pub framerate: u32,
190 pub components: Vec<String>,
192 }
193}
194
195#[cfg(test)]
196mod test {
197 use super::gateway::ResProtocolRequest;
198
199 #[test]
200 fn test_resprotocol_roundtrip() {
201 let mut subject = "call.decs.components.the_void.player1.radar_contacts.new";
202 let mut req = ResProtocolRequest::from(subject);
203 assert_eq!(
204 req,
205 ResProtocolRequest::New("decs.components.the_void.player1.radar_contacts".into())
206 );
207 assert_eq!(
208 req.to_string(),
209 "call.decs.components.the_void.player1.radar_contacts.new"
210 );
211
212 subject = "call.decs.components.the_void.player1.radar_contacts.delete";
213 req = ResProtocolRequest::from(subject);
214 assert_eq!(
215 req,
216 ResProtocolRequest::Delete("decs.components.the_void.player1.radar_contacts".into())
217 );
218 assert_eq!(
219 req.to_string(),
220 "call.decs.components.the_void.player1.radar_contacts.delete"
221 );
222
223 subject = "get.decs.components.the_void.player1.radar_contacts.1";
224 req = ResProtocolRequest::from(subject);
225 assert_eq!(
226 req,
227 ResProtocolRequest::Get("decs.components.the_void.player1.radar_contacts.1".into())
228 );
229 assert_eq!(
230 req.to_string(),
231 "get.decs.components.the_void.player1.radar_contacts.1"
232 );
233
234 subject = "call.decs.components.the_void.player1.position.set";
235 req = ResProtocolRequest::from(subject);
236 assert_eq!(
237 req,
238 ResProtocolRequest::Set("decs.components.the_void.player1.position".into())
239 );
240 assert_eq!(
241 req.to_string(),
242 "call.decs.components.the_void.player1.position.set"
243 );
244
245 subject = "access.decs.components.the_void.player1.radar_contacts.1";
246 req = ResProtocolRequest::from(subject);
247 assert_eq!(
248 req,
249 ResProtocolRequest::Access("decs.components.the_void.player1.radar_contacts.1".into())
250 );
251 assert_eq!(
252 req.to_string(),
253 "access.decs.components.the_void.player1.radar_contacts.1"
254 );
255
256 subject = "call.decs.shard.the_void.set";
257 req = ResProtocolRequest::from(subject);
258 assert_eq!(req, ResProtocolRequest::Set("decs.shard.the_void".into()));
259 assert_eq!(req.to_string(), "call.decs.shard.the_void.set");
260
261 subject = "call.decs.shard.the_void.incr";
262 req = ResProtocolRequest::from(subject);
263 assert_eq!(
264 req,
265 ResProtocolRequest::Call("decs.shard.the_void".into(), "incr".into())
266 );
267 assert_eq!(req.to_string(), "call.decs.shard.the_void.incr");
268 }
269}