jmdict_load/
lib.rs

1//! [jmdict-rs][jmdict-rs] dependency responsible for retrieving dictionary data.
2//!
3//! # License
4//!
5//! ## JMdict
6//!
7//! The origin of **JMdict** in the form of a JSON file is the repository [jmdict-simplified][jmdict-simplified].
8//! In view of this, the said file is subject to the same license as its original source, namely **JMdict.xml**,
9//! which is the intellectual property of the Electronic Dictionary Research and Development Group.
10//! See [EDRDG License][EDRDG-license]
11//!
12//! ## Other files
13//!
14//! Source code and the rest of the files in this project are licensed under [Apache License, Version 2.0][Apache-2.0].
15//!
16//! [jmdict-simplified]: https://github.com/scriptin/jmdict-simplified
17//! [EDRDG-license]: http://www.edrdg.org/edrdg/licence.html
18//! [Apache-2.0]: http://www.apache.org/licenses/LICENSE-2.0
19//! [jmdict-rs]: https://docs.rs/jmdict-rs
20
21use 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}