generated from sindresorhus/electron-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 138
/
web.rs
173 lines (150 loc) · 4.54 KB
/
web.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
use std::collections::HashMap;
use futures::future::try_join3;
use reqwest::header::USER_AGENT;
use serde::{Deserialize, Serialize};
use tracing::error;
use crate::{
builds::{self, ItemBuild, BuildData},
source::SourceItem,
utils::VERSION,
};
pub const SERVICE_URL: &str = "https://ql-rs.lbj.moe";
#[derive(Debug, Clone)]
pub enum FetchError {
Failed,
}
pub async fn fetch_sources() -> Result<Vec<SourceItem>, FetchError> {
let url = format!("{SERVICE_URL}/api/sources");
if let Ok(resp) = reqwest::get(url).await {
if let Ok(list) = resp.json::<Vec<SourceItem>>().await {
return Ok(list);
}
}
Err(FetchError::Failed)
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChampInfo {
pub version: String,
pub id: String,
pub key: String,
pub name: String,
pub title: String,
// pub blurb: String,
// pub info: Info,
pub image: Image,
pub tags: Vec<String>,
// pub partype: String,
// pub stats: Stats,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Image {
pub full: String,
pub sprite: String,
pub group: String,
pub x: u32,
pub y: u32,
pub w: u32,
pub h: u32,
}
pub type ChampionsMap = HashMap<String, ChampInfo>;
pub async fn fetch_champion_list() -> Result<ChampionsMap, FetchError> {
let url = format!("{SERVICE_URL}/api/data-dragon/champions",);
if let Ok(resp) = reqwest::get(url).await {
if let Ok(data) = resp.json::<ChampionsMap>().await {
return Ok(data);
}
}
Err(FetchError::Failed)
}
pub async fn init_for_ui(
) -> Result<(Vec<SourceItem>, ChampionsMap, Vec<DataDragonRune>), FetchError> {
try_join3(
fetch_sources(),
fetch_champion_list(),
fetch_data_dragon_runes(),
)
.await
}
pub async fn fetch_build_file(
source: &String,
champion: &String,
fetch_build: bool,
) -> Result<Vec<builds::BuildSection>, FetchError> {
let path = if fetch_build { "builds" } else { "runes" };
let url = format!("{SERVICE_URL}/api/source/{source}/{path}/{champion}");
if let Ok(resp) = reqwest::get(url).await {
if let Ok(data) = resp.json::<Vec<builds::BuildSection>>().await {
return Ok(data);
}
}
Err(FetchError::Failed)
}
pub async fn fetch_champion_runes(
source: String,
champion: String,
) -> Result<BuildData, FetchError> {
let meta = fetch_build_file(&source, &champion, false).await?;
let runes = meta.iter().flat_map(|b| b.runes.clone()).collect();
let builds: Vec<ItemBuild> = meta.iter().flat_map(|b| b.item_builds.clone()).collect();
Ok(BuildData(runes, builds))
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Slot {
pub runes: Vec<SlotRune>,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SlotRune {
pub id: u64,
pub key: String,
pub icon: String,
pub name: String,
pub short_desc: String,
pub long_desc: String,
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataDragonRune {
pub id: u64,
pub key: String,
pub icon: String,
pub name: String,
pub slots: Vec<Slot>,
}
pub async fn fetch_data_dragon_runes() -> Result<Vec<DataDragonRune>, FetchError> {
if let Ok(resp) = reqwest::get(format!("{SERVICE_URL}/api/data-dragon/runes")).await {
if let Ok(data) = resp.json::<Vec<DataDragonRune>>().await {
return Ok(data);
}
}
Err(FetchError::Failed)
}
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LatestRelease {
pub name: String,
pub tag_name: String,
pub html_url: String,
}
pub async fn fetch_latest_release() -> Result<LatestRelease, FetchError> {
let client = reqwest::Client::new();
match client
.get("https://api.github.com/repos/cangzhang/champ-r/releases/latest".to_string())
.header(USER_AGENT, format!("ChampR {VERSION}"))
.send()
.await
{
Ok(resp) => {
resp.json::<LatestRelease>().await.map_err(|err| {
error!("latest release serialize: {:?}", err);
FetchError::Failed
})
}
Err(err) => {
error!("fetch latest release: {:?}", err);
Err(FetchError::Failed)
}
}
}