Skip to content

Commit 3430874

Browse files
authored
feat: simplified fetch to replace the array specific fetch
fix: made `StatisticsItem` moving_avg optional BREAKING CHANGE: replaced fetch_arr, RT traits, and Model trait with the new Queryable trait
1 parent 604dfca commit 3430874

19 files changed

+140
-178
lines changed

.vscode/test.code-snippets

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
" async fn test_${1/(.*)/${1:/downcase}/}() -> Result<(), ApiError> {",
5656
" let client = Client::new();",
5757
"",
58-
" match client.fetch_arr::<${1:model}>().await {",
58+
" match client.fetch::<${1:model}>().await {",
5959
" Ok(_${1/(.*)/${1:/downcase}/}s) => Ok(()),",
6060
" Err(why) => Err(why),",
6161
" }",
@@ -68,7 +68,7 @@
6868
"",
6969
" let client = Client::new();",
7070
"",
71-
" match client.fetch_arr_using_lang::<${1:model}>(Language::ZH).await {",
71+
" match client.fetch_using_lang::<${1:model}>(Language::ZH).await {",
7272
" Ok(_${1/(.*)/${1:/downcase}/}s) => Ok(()),",
7373
" Err(why) => Err(why),",
7474
" }",

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ market_full = ["market", "market_cache"]
2323

2424
[dependencies]
2525
tokio = { version = "1.34.0", features = ["full"] }
26-
reqwest = { version = "0.11.22", features = ["json"] }
26+
reqwest = { version = "0.12.5", features = ["json"] }
2727
chrono = { version = "0.4.31", features = ["serde", "clock"] }
2828
serde = { version = "1.0.190", features = ["derive"] }
2929
serde_json = { version = "1.0.108" }

src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![doc = include_str!("../README.md")]
2+
13
#[cfg(feature = "worldstate")]
24
pub mod worldstate;
35

@@ -9,6 +11,6 @@ pub(crate) mod ws {
911
pub(crate) use crate::worldstate::language::Language;
1012
pub(crate) use crate::worldstate::models::base::*;
1113
pub(crate) use crate::worldstate::models::macros::{
12-
impl_endpoint, impl_model_struct, impl_rt, impl_timed_event,
14+
impl_model_struct, impl_queryable, impl_timed_event,
1315
};
1416
}

src/market/models/statistic_item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub struct StatisticsClosed48Hour {
4343

4444
pub median: f64,
4545

46-
pub moving_avg: f64,
46+
pub moving_avg: Option<f64>,
4747

4848
pub donch_top: f64,
4949

@@ -79,7 +79,7 @@ pub struct StatisticsLive48Hour {
7979

8080
pub order_type: OrderType,
8181

82-
pub moving_avg: f64,
82+
pub moving_avg: Option<f64>,
8383

8484
pub id: String,
8585
}

src/worldstate/client.rs

+23-81
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use super::error::{ApiError, ApiErrorResponse};
1+
use crate::ws::Queryable;
2+
#[allow(unused)]
3+
use crate::ws::TimedEvent;
24

3-
use super::models::base::{Endpoint, Model, RTArray, RTObject};
5+
use super::error::ApiError;
46

57
#[derive(Default, Debug, Clone)]
68
pub struct Client {
@@ -15,35 +17,11 @@ impl Client {
1517

1618
// impl FETCH
1719
impl Client {
18-
pub async fn fetch<T>(&self) -> Result<T, ApiError>
20+
pub async fn fetch<T>(&self) -> Result<T::Return, ApiError>
1921
where
20-
T: Model + Endpoint + RTObject,
22+
T: Queryable,
2123
{
22-
let response = self.session.get(T::endpoint_en()).send().await?;
23-
24-
if response.status().is_success() {
25-
dbg!("Request came through");
26-
let json_result = response.json::<T>().await?;
27-
Ok(json_result)
28-
} else {
29-
let error_response = response.json::<ApiErrorResponse>().await?;
30-
Err(ApiError::ApiError(error_response))
31-
}
32-
}
33-
34-
pub async fn fetch_arr<T>(&self) -> Result<Vec<T>, ApiError>
35-
where
36-
T: Model + Endpoint + RTArray,
37-
{
38-
let response = self.session.get(T::endpoint_en()).send().await?;
39-
40-
if response.status().is_success() {
41-
let json_result = response.json::<Vec<T>>().await?;
42-
Ok(json_result)
43-
} else {
44-
let error_response = response.json::<ApiErrorResponse>().await?;
45-
Err(ApiError::ApiError(error_response))
46-
}
24+
<T as Queryable>::query(&self.session).await
4725
}
4826
}
4927

@@ -58,7 +36,7 @@ impl Client {
5836
///
5937
/// # Generic Constraints
6038
///
61-
/// - `T`: Must implement the `Model`, `Endpoint`, `RTObject`, and `TimedEvent` traits.
39+
/// - `T`: Must implement the `Queryable` and `TimedEvent` traits.
6240
/// - `Callback`: Must implement the `ListenerCallback` trait with a lifetime parameter `'any` and type parameter `T`.
6341
///
6442
/// # Returns
@@ -92,7 +70,7 @@ impl Client {
9270
/// ```
9371
pub async fn call_on_update<T, Callback>(&self, callback: Callback) -> Result<(), ApiError>
9472
where
95-
T: Model + Endpoint + RTObject + crate::worldstate::models::TimedEvent,
73+
T: TimedEvent + Queryable<Return = T>,
9674
for<'any> Callback: crate::worldstate::listener::ListenerCallback<'any, T>,
9775
{
9876
log::debug!("{} (LISTENER) :: Started", std::any::type_name::<T>());
@@ -134,7 +112,7 @@ impl Client {
134112
///
135113
/// # Generic Constraints
136114
///
137-
/// - `T`: Must implement the `Model`, `Endpoint`, `RTObject`, and `TimedEvent` traits.
115+
/// - `T`: Must implement the `Queryable`, `TimedEvent` and `PartialEq` traits.
138116
/// - `Callback`: Must implement the `ListenerCallback` trait with a lifetime parameter `'any` and type parameter `T`.
139117
///
140118
/// # Returns
@@ -180,11 +158,11 @@ impl Client {
180158
callback: Callback,
181159
) -> Result<(), ApiError>
182160
where
183-
T: Model + Endpoint + RTArray + crate::worldstate::models::TimedEvent + PartialEq,
161+
T: TimedEvent + Queryable<Return = Vec<T>> + PartialEq,
184162
for<'any> Callback: crate::worldstate::listener::NestedListenerCallback<'any, T>,
185163
{
186164
log::debug!("{} (LISTENER) :: Started", std::any::type_name::<Vec<T>>());
187-
let mut items = self.fetch_arr::<T>().await?;
165+
let mut items = self.fetch::<T>().await?;
188166

189167
loop {
190168
tokio::time::sleep(std::time::Duration::from_secs(30)).await;
@@ -193,7 +171,7 @@ impl Client {
193171
"{} (LISTENER) :: Fetching new possible state",
194172
std::any::type_name::<Vec<T>>()
195173
);
196-
let new_items = self.fetch_arr::<T>().await?;
174+
let new_items = self.fetch::<T>().await?;
197175

198176
let diff = crate::worldstate::listener::CrossDiff::new(&items, &new_items);
199177

@@ -229,7 +207,7 @@ impl Client {
229207
/// # Generic Parameters
230208
///
231209
/// - `S`: The type of the state object. It must be `Sized`, `Send`, `Sync`, and `Clone`.
232-
/// - `T`: The type of the item. It must implement the `Model`, `Endpoint`, `RTObject`, and `TimedEvent` traits.
210+
/// - `T`: Must implement the `Queryable` and `TimedEvent` traits.
233211
/// - `Callback`: The type of the callback function. It must implement the `StatefulListenerCallback` trait with the item type `T` and the state type `S`.
234212
///
235213
/// # Returns
@@ -283,7 +261,7 @@ impl Client {
283261
) -> Result<(), ApiError>
284262
where
285263
S: Sized + Send + Sync + Clone,
286-
T: Model + Endpoint + RTObject + crate::worldstate::models::TimedEvent,
264+
T: TimedEvent + Queryable<Return = T>,
287265
for<'any> Callback: crate::worldstate::listener::StatefulListenerCallback<'any, T, S>,
288266
{
289267
let mut item = self.fetch::<T>().await?;
@@ -328,7 +306,7 @@ impl Client {
328306
/// # Generic Constraints
329307
///
330308
/// * `S` - The type of the state, which must be `Sized`, `Send`, `Sync`, and `Clone`.
331-
/// * `T` - The type of the items, which must implement the `Model`, `Endpoint`, `RTArray`, `TimedEvent`, and `PartialEq` traits.
309+
/// * `T` - Must implement the `Queryable`, `TimedEvent` and `PartialEq` traits.
332310
/// * `Callback` - The type of the callback function, which must implement the `StatefulNestedListenerCallback` trait.
333311
///
334312
/// # Returns
@@ -383,11 +361,11 @@ impl Client {
383361
) -> Result<(), ApiError>
384362
where
385363
S: Sized + Send + Sync + Clone,
386-
T: Model + Endpoint + RTArray + crate::worldstate::models::TimedEvent + PartialEq,
364+
T: Queryable<Return = Vec<T>> + TimedEvent + PartialEq,
387365
for<'any> Callback: crate::worldstate::listener::StatefulNestedListenerCallback<'any, T, S>,
388366
{
389367
log::debug!("{} (LISTENER) :: Started", std::any::type_name::<Vec<T>>());
390-
let mut items = self.fetch_arr::<T>().await?;
368+
let mut items = self.fetch::<T>().await?;
391369

392370
loop {
393371
tokio::time::sleep(std::time::Duration::from_secs(30)).await;
@@ -396,7 +374,7 @@ impl Client {
396374
"{} (LISTENER) :: Fetching new possible state",
397375
std::any::type_name::<Vec<T>>()
398376
);
399-
let new_items = self.fetch_arr::<T>().await?;
377+
let new_items = self.fetch::<T>().await?;
400378

401379
let diff = crate::worldstate::listener::CrossDiff::new(&items, &new_items);
402380

@@ -424,47 +402,11 @@ impl Client {
424402
impl Client {
425403
pub async fn fetch_using_lang<T>(
426404
&self,
427-
language: super::language::Language,
428-
) -> Result<T, ApiError>
405+
language: crate::ws::Language,
406+
) -> Result<T::Return, ApiError>
429407
where
430-
T: Model + Endpoint + RTObject,
408+
T: Queryable,
431409
{
432-
let response = self
433-
.session
434-
.get(T::endpoint(language))
435-
.send()
436-
.await
437-
.unwrap();
438-
439-
if response.status().is_success() {
440-
let json_result = response.json::<T>().await?;
441-
Ok(json_result)
442-
} else {
443-
let error_response = response.json::<ApiErrorResponse>().await?;
444-
Err(ApiError::ApiError(error_response))
445-
}
446-
}
447-
448-
pub async fn fetch_arr_using_lang<T>(
449-
&self,
450-
language: super::language::Language,
451-
) -> Result<Vec<T>, ApiError>
452-
where
453-
T: Model + Endpoint + RTArray,
454-
{
455-
let response = self
456-
.session
457-
.get(T::endpoint(language))
458-
.send()
459-
.await
460-
.unwrap();
461-
462-
if response.status().is_success() {
463-
let json_result = response.json::<Vec<T>>().await?;
464-
Ok(json_result)
465-
} else {
466-
let error_response = response.json::<ApiErrorResponse>().await?;
467-
Err(ApiError::ApiError(error_response))
468-
}
410+
T::query_with_language(&self.session, language).await
469411
}
470412
}

src/worldstate/listener.rs

+23-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::future::Future;
22

3-
use super::models::{Endpoint, Model, RTArray, RTObject};
4-
53
#[derive(PartialEq, PartialOrd, Debug, Clone)]
64
pub enum Change {
75
Added,
@@ -11,15 +9,15 @@ pub enum Change {
119
// ----------
1210
pub trait ListenerCallback<'a, T>
1311
where
14-
T: Sized + Endpoint + RTObject + Model,
12+
T: Sized + 'a,
1513
{
1614
type Fut: Future + Send;
1715
fn call(&self, before: &'a T, after: &'a T) -> Self::Fut;
1816
}
1917

2018
impl<'a, T, Fut, Func> ListenerCallback<'a, T> for Func
2119
where
22-
T: Sized + Endpoint + RTObject + Model + 'a,
20+
T: Sized + 'a,
2321
Fut: Future + Send,
2422
Func: Fn(&'a T, &'a T) -> Fut,
2523
{
@@ -31,15 +29,15 @@ where
3129

3230
pub trait NestedListenerCallback<'a, T>
3331
where
34-
T: Sized + Endpoint + RTArray + Model,
32+
T: Sized,
3533
{
3634
type Fut: Future + Send;
3735
fn call(&self, item: &'a T, change: Change) -> Self::Fut;
3836
}
3937

4038
impl<'a, T, Fut, Func> NestedListenerCallback<'a, T> for Func
4139
where
42-
T: Sized + Endpoint + RTArray + Model + 'a,
40+
T: Sized + 'a,
4341
Fut: Future + Send,
4442
Func: Fn(&'a T, Change) -> Fut,
4543
{
@@ -52,7 +50,7 @@ where
5250
// --------- STATEFUL CALLBACKS
5351
pub trait StatefulListenerCallback<'a, T, S>
5452
where
55-
T: Sized + Endpoint + RTObject + Model,
53+
T: Sized,
5654
S: Sized + Send + Sync,
5755
{
5856
type Fut: Future + Send;
@@ -61,7 +59,7 @@ where
6159

6260
impl<'a, T, Fut, Func, S> StatefulListenerCallback<'a, T, S> for Func
6361
where
64-
T: Sized + Endpoint + RTObject + Model + 'a,
62+
T: Sized + 'a,
6563
S: Sized + Send + Sync,
6664
Fut: Future + Send,
6765
Func: Fn(S, &'a T, &'a T) -> Fut,
@@ -74,7 +72,7 @@ where
7472

7573
pub trait StatefulNestedListenerCallback<'a, T, S>
7674
where
77-
T: Sized + Endpoint + RTArray + Model,
75+
T: Sized,
7876
S: Sized + Send + Sync,
7977
{
8078
type Fut: Future + Send;
@@ -83,7 +81,7 @@ where
8381

8482
impl<'a, T, Fut, Func, S> StatefulNestedListenerCallback<'a, T, S> for Func
8583
where
86-
T: Sized + Endpoint + RTArray + Model + 'a,
84+
T: Sized + 'a,
8785
S: Sized + Send + Sync,
8886
Fut: Future + Send,
8987
Func: Fn(S, &'a T, Change) -> Fut,
@@ -136,7 +134,10 @@ mod test {
136134
use super::{Change, CrossDiff};
137135

138136
async fn on_cetus_update(_before: &Cetus, _after: &Cetus) {}
139-
async fn on_cetus_update_stateful_nested(_state: Arc<i32>, _item: &Fissure, _change: Change) {}
137+
async fn on_cetus_update_stateful(_state: Arc<i32>, _before: &Cetus, _after: &Cetus) {}
138+
async fn on_fissure_update_nested(_item: &Fissure, _change: Change) {}
139+
async fn on_fissure_update_stateful_nested(_state: Arc<i32>, _item: &Fissure, _change: Change) {
140+
}
140141

141142
#[tokio::test]
142143
async fn test() {
@@ -148,7 +149,17 @@ mod test {
148149
let cloned = client.clone();
149150
tokio::task::spawn(async move {
150151
cloned
151-
.call_on_nested_update_with_state(on_cetus_update_stateful_nested, Arc::new(4))
152+
.call_on_update_with_state(on_cetus_update_stateful, Arc::new(4))
153+
.await
154+
});
155+
let cloned = client.clone();
156+
tokio::task::spawn(
157+
async move { cloned.call_on_nested_update(on_fissure_update_nested).await },
158+
);
159+
let cloned = client.clone();
160+
tokio::task::spawn(async move {
161+
cloned
162+
.call_on_nested_update_with_state(on_fissure_update_stateful_nested, Arc::new(4))
152163
.await
153164
});
154165
}

src/worldstate/models/alert.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mod test {
2727
async fn test_alert() -> Result<(), ApiError> {
2828
let client = Client::new();
2929

30-
match client.fetch_arr::<Alert>().await {
30+
match client.fetch::<Alert>().await {
3131
Ok(_alerts) => Ok(()),
3232
Err(why) => Err(why),
3333
}
@@ -40,7 +40,7 @@ mod test {
4040

4141
let client = Client::new();
4242

43-
match client.fetch_arr_using_lang::<Alert>(Language::ZH).await {
43+
match client.fetch_using_lang::<Alert>(Language::ZH).await {
4444
Ok(_alerts) => Ok(()),
4545
Err(why) => Err(why),
4646
}

0 commit comments

Comments
 (0)