1use std::io::{Cursor, Read};
22
23use flate2::read::GzDecoder;
24use reqwest::header::USER_AGENT;
25use serde::{Deserialize, Serialize};
26use tar::Archive;
27
28const LATEST: &str = "https://api.github.com/repos/scriptin/jmdict-simplified/releases/latest";
29
30#[derive(Serialize, Deserialize, Debug, Clone)]
31pub struct Release {
32 pub id: u32,
33 pub name: String,
34 pub assets: Vec<Asset>,
35}
36
37#[derive(Serialize, Deserialize, Debug, Clone)]
38pub struct Asset {
39 pub id: u32,
40 pub name: String,
41 pub size: u32,
42 pub browser_download_url: String,
43}
44
45fn get_latest_release_url() -> Result<String, Box<dyn std::error::Error>> {
46 let client = reqwest::blocking::Client::new();
47 let response = client
48 .get(LATEST)
49 .header(USER_AGENT, "jmdict-rs")
50 .send();
51
52 let release = response?.json::<Release>()?;
53
54 let download_url = release
55 .assets
56 .iter()
57 .find(|a|
58 a.name.contains("jmdict-eng") && !a.name.contains("common")
59 )
60 .map(|a| a.browser_download_url.clone())
61 .unwrap();
62
63 Ok(download_url)
64}
65
66pub fn download_jm_dict() -> Result<String, Box<dyn std::error::Error>> {
67 let latest_url = get_latest_release_url()?;
68
69 let response = reqwest::blocking::get(latest_url)?;
70 let content = Cursor::new(response.bytes()?);
71
72 let tar = GzDecoder::new(content);
73 let mut archive = Archive::new(tar);
74
75 let mut entry = archive.entries()?.next().unwrap()?;
76
77 let mut res = String::new();
78 entry.read_to_string(&mut res)?;
79
80 Ok(res)
81}