Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chimei-ruiju.orgへの対応: main(v0.1.21)との差分を取り込み #488

Merged
merged 54 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
3e06bd4
add: #470: `experimental`モジュールを作成
YuukiToriyama Oct 20, 2024
3d48e53
add: #470: `experimental`モジュールに`Parser`構造体を定義
YuukiToriyama Oct 20, 2024
735ebc0
add: #470: `Parser#parse`を実装
YuukiToriyama Oct 20, 2024
556c687
update: #470: `log`クレートの依存を追加
YuukiToriyama Oct 20, 2024
90bf1e7
add: #470: `ParserOptions`にフィールド`correct_incomplete_city_names`を追加
YuukiToriyama Oct 20, 2024
33584cf
update: #470: `Parser#parse_with_geolonia`を実装
YuukiToriyama Oct 20, 2024
2146b09
update: #470: `ParseOptions`にフィールド`verbose`を追加
YuukiToriyama Oct 20, 2024
2d97d7e
update: #470: `Parser`の可視性をpublicに変更
YuukiToriyama Oct 20, 2024
b711888
fix: #470: 不要なimportを削除
YuukiToriyama Oct 20, 2024
f167af2
update: #470: `parse_with_geolonia()`に対してテストコードを追加
YuukiToriyama Oct 20, 2024
907ba63
update: #470: `experimental`モジュールのテストもCIで実行するように修正
YuukiToriyama Oct 20, 2024
89f8fe6
update: #470: experimentalモジュールのドキュメントに注意文言を追加
YuukiToriyama Oct 21, 2024
0eb7095
fix: #470: `ParserOptions`のフィールドをpublicに変更
YuukiToriyama Oct 21, 2024
9db0249
fix: #470: `Parser`のフィールドをpublicに変更
YuukiToriyama Oct 21, 2024
95eda52
update: #470: `ParserOptions`にドキュメントを追加
YuukiToriyama Oct 21, 2024
c157d93
update: #470: publicな構造体にDebugトレイトを実装
YuukiToriyama Oct 21, 2024
1c1d2a9
update: #470: `Parser`とそのメソッドにドキュメントを追加
YuukiToriyama Oct 21, 2024
eedcf7e
update: #470: `DataSource`に対してドキュメントを追加
YuukiToriyama Oct 21, 2024
9cf1c4a
Merge pull request #471 from YuukiToriyama/feature/re-design-parser/e…
YuukiToriyama Oct 21, 2024
b7041f8
update: #470: `Token`に`PartialOrd`を実装
YuukiToriyama Oct 21, 2024
9ad36b8
Merge pull request #474 from YuukiToriyama/feature/re-design-parser/i…
YuukiToriyama Oct 27, 2024
7842f8e
add: #470: 構造体`ParsedAddress`および`Metadata`を定義
YuukiToriyama Oct 27, 2024
9ba07c2
add: #470: `Vec<Token>`から`ParsedAddress`に変換するためのメソッドを実装
YuukiToriyama Oct 27, 2024
fa00747
update: #470: `ParsedAddress::from(tokens)`に対してテストコードを作成
YuukiToriyama Oct 27, 2024
4f0cb93
update: #470: `Parser#parse`の返り値を`Vec<Token>`から`ParsedAddress`に変更
YuukiToriyama Oct 27, 2024
1540d5d
fix: #470: `parse_with_geolonia()`に対するテストコードが壊れていたので修正
YuukiToriyama Oct 27, 2024
0392403
Merge pull request #475 from YuukiToriyama/feature/re-design-parser/c…
YuukiToriyama Oct 27, 2024
fac3679
update: #470: wasmクレートの`nightly`フィーチャでcoreクレートの`experimental`フィーチャが使用…
YuukiToriyama Oct 27, 2024
c377f0b
add: #470: `wasm`クレートに`nightly`モジュールを追加
YuukiToriyama Oct 27, 2024
16854fe
update: #470: wasm内で発生したエラーや警告をJavaScript側にログ出力できるように設定
YuukiToriyama Oct 27, 2024
f8518e7
update: #470: `ParsedAddress`をJSONにシリアライズできるように`serde::Serialize`トレイとを実装
YuukiToriyama Oct 27, 2024
37a9167
update: #470: `DataSource`に`Default`クレートを実装
YuukiToriyama Oct 27, 2024
f099bf6
add: #470: `parse_experimental(address: string, options: ParseOptions…
YuukiToriyama Oct 27, 2024
edcb55f
update: #470: `parse_experiment`についてJSDocを自動生成しないように設定
YuukiToriyama Oct 27, 2024
38c2484
Merge pull request #476 from YuukiToriyama/feature/re-design-parser/f…
YuukiToriyama Oct 27, 2024
46f20f6
update: #470: `nightly.html`での処理を旧来の`Parser`ベースではなく新しく追加した`parse_expe…
YuukiToriyama Oct 27, 2024
9bdfe18
update: #470: Parserに与えるオプションの一部をページ上から変更できるようにした
YuukiToriyama Oct 27, 2024
f489b85
Merge pull request #477 from YuukiToriyama/feature/re-design-parser/n…
YuukiToriyama Oct 28, 2024
239b379
update: #470: `experimental`モジュールもdocs.rsに反映されるように設定
YuukiToriyama Oct 28, 2024
d37e8ae
Merge pull request #478 from YuukiToriyama/feature/re-design-parser/docs
YuukiToriyama Oct 28, 2024
5c1af4c
update-version: 0.1.19 -> 0.1.20
YuukiToriyama Oct 28, 2024
c04cc07
Merge pull request #479 from YuukiToriyama/feature/re-design-parser/m…
YuukiToriyama Oct 28, 2024
42788b9
Merge pull request #480 from YuukiToriyama/release/v0.1.20
YuukiToriyama Oct 28, 2024
9981c5c
fix: ParsedAddressの修正: `Metadata`のフィールドをprivateからpublicに変更
YuukiToriyama Oct 28, 2024
4b0afe1
fix: ParsedAddressの修正: `ParsedAddress`のフィールドをprivateからpublicに変更
YuukiToriyama Oct 28, 2024
5e808a3
Merge pull request #482 from YuukiToriyama/feature/fix-parsed-address…
YuukiToriyama Oct 28, 2024
383fe87
fix: ParsedAddressの修正: `Parser#parse`の説明が適切でなかったので修正
YuukiToriyama Oct 28, 2024
89b5bce
fix: ParsedAddressの修正: `Parser#parse`のサンプルコードを修正
YuukiToriyama Oct 28, 2024
146f256
update-version: 0.1.20 -> 0.1.21
YuukiToriyama Oct 28, 2024
a482e99
Merge pull request #483 from YuukiToriyama/feature/fix-parsed-address…
YuukiToriyama Oct 28, 2024
f43d6a2
fix: rustdocのTypoを修正
YuukiToriyama Oct 29, 2024
527bbe3
Merge pull request #485 from YuukiToriyama/feature/fix-parsed-address…
YuukiToriyama Oct 29, 2024
79b5249
Merge pull request #484 from YuukiToriyama/feature/fix-parsed-address…
YuukiToriyama Oct 29, 2024
ee97b64
Merge pull request #486 from YuukiToriyama/release/v0.1.21
YuukiToriyama Oct 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/run-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
run: |
cargo test
cargo test --features=blocking
cargo test --features=experimental
- name: Integration test
working-directory: tests
run: cargo test
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
resolver = "2"

[workspace.package]
version = "0.1.19"
version = "0.1.21"
edition = "2021"
description = "A Rust Library to parse japanese addresses."
repository = "https://github.com/YuukiToriyama/japanese-address-parser"
Expand All @@ -18,6 +18,7 @@ keywords = ["parser", "geo", "wasm"]
categories = ["parser-implementations", "wasm"]

[workspace.dependencies]
log = "0.4.22"
serde = { version = "1.0.192", features = ["derive"] }
tokio = { version = "1.38.0", features = ["rt", "macros"] }
wasm-bindgen = "0.2.92"
Expand Down
7 changes: 7 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ blocking = ["reqwest/blocking"]
city-name-correction = []
format-house-number = []
eliminate-whitespaces = []
experimental = []

[[bench]]
name = "core_benchmark"
harness = false

[dependencies]
itertools = "0.13.0"
log.workspace = true
rapidfuzz = "0.5.0"
regex = { version = "1.10.6", default-features = false, features = ["std", "unicode-perl"] }
serde.workspace = true
Expand All @@ -42,3 +44,8 @@ wasm-bindgen-test = { workspace = true }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
mockito = "1.4.0" # mockitoがwasm32に対応していないため

[package.metadata.docs.rs]
all-features = true
targets = ["x86_64-unknown-linux-gnu"]
rustdoc-args = ["--cfg", "docsrs"]
6 changes: 3 additions & 3 deletions core/src/domain/common/latlng.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#[derive(Clone, Debug, PartialEq)]
pub struct LatLng {
/// 緯度
latitude: f64,
/// 軽度
longitude: f64,
pub(crate) latitude: f64,
/// 経度
pub(crate) longitude: f64,
}
76 changes: 76 additions & 0 deletions core/src/domain/common/token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::domain::common::latlng::LatLng;
use std::cmp::Ordering;
use std::cmp::Ordering::{Equal, Greater, Less};

#[derive(Clone, Debug, PartialEq)]
pub enum Token {
Expand All @@ -8,6 +10,37 @@ pub enum Token {
Rest(String),
}

impl PartialOrd for Token {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self {
Token::Prefecture(_) => match other {
Token::Prefecture(_) => Some(Equal),
Token::City(_) => Some(Less),
Token::Town(_) => Some(Less),
Token::Rest(_) => Some(Less),
},
Token::City(_) => match other {
Token::Prefecture(_) => Some(Greater),
Token::City(_) => Some(Equal),
Token::Town(_) => Some(Less),
Token::Rest(_) => Some(Less),
},
Token::Town(_) => match other {
Token::Prefecture(_) => Some(Greater),
Token::City(_) => Some(Greater),
Token::Town(_) => Some(Equal),
Token::Rest(_) => Some(Less),
},
Token::Rest(_) => match other {
Token::Prefecture(_) => Some(Greater),
Token::City(_) => Some(Greater),
Token::Town(_) => Some(Greater),
Token::Rest(_) => Some(Equal),
},
}
}
}

#[derive(Debug, PartialEq, Clone)]
pub(crate) struct Prefecture {
pub(crate) prefecture_name: String,
Expand All @@ -29,3 +62,46 @@ pub(crate) struct Town {
pub(crate) fn append_token(tokens: &[Token], token: Token) -> Vec<Token> {
[tokens.to_owned(), vec![token]].concat()
}

#[cfg(test)]
mod tests {
use crate::domain::common::token::{City, Prefecture, Token, Town};

#[test]
fn sort_token_vector() {
let mut tokens = vec![
Token::Rest("2-1".to_string()),
Token::City(City {
city_name: "小金井市".to_string(),
representative_point: None,
}),
Token::Prefecture(Prefecture {
prefecture_name: "東京都".to_string(),
representative_point: None,
}),
Token::Town(Town {
town_name: "貫井北町四丁目".to_string(),
representative_point: None,
}),
];
tokens.sort_by(|a, b| a.partial_cmp(b).unwrap());
assert_eq!(
tokens,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "東京都".to_string(),
representative_point: None,
}),
Token::City(City {
city_name: "小金井市".to_string(),
representative_point: None,
}),
Token::Town(Town {
town_name: "貫井北町四丁目".to_string(),
representative_point: None,
}),
Token::Rest("2-1".to_string()),
]
);
}
}
10 changes: 10 additions & 0 deletions core/src/experimental.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! 🚧 Experimental module 🚧
//!
//! This module contains unstable functions.
//!
//! Please note that these functions may be removed or changed disruptively without any announcement.
//!
//! If you are eager to use this module, please enable `experimental` feature flag.

mod parse_with_geolonia;
pub mod parser;
193 changes: 193 additions & 0 deletions core/src/experimental/parse_with_geolonia.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
use crate::api::AsyncApi;
use crate::domain::common::token::Token;
use crate::experimental::parser::Parser;
use crate::tokenizer::Tokenizer;

impl Parser {
#[inline]
pub(crate) async fn parse_with_geolonia(&self, address: &str) -> Vec<Token> {
let geolonia_api = AsyncApi::default();
let tokenizer = Tokenizer::new(address);

// 都道府県名の検出
let (prefecture, tokenizer) = match tokenizer.read_prefecture() {
Ok(found) => found,
Err(not_found) => {
if self.options.verbose {
log::error!("都道府県名の検出に失敗しました")
}
return not_found.tokens;
}
};

// 市区町村名の検出
let prefecture_master = match geolonia_api
.get_prefecture_master(prefecture.name_ja())
.await
{
Ok(result) => result,
Err(error) => {
if self.options.verbose {
log::error!("{}", error.error_message)
}
return tokenizer.finish().tokens;
}
};
let (city_name, tokenizer) = match tokenizer.read_city(&prefecture_master.cities) {
Ok(found) => found,
Err(not_found) => {
if self.options.correct_incomplete_city_names {
match not_found.read_city_with_county_name_completion(&prefecture_master.cities)
{
Ok(result) => result,
Err(not_found) => {
if self.options.verbose {
log::error!("市区町村名の検出に失敗しました")
}
return not_found.tokens;
}
}
} else {
if self.options.verbose {
log::error!("市区町村名の検出に失敗しました")
}
return not_found.finish().tokens;
}
}
};

// 町名の検出
let city_master = match geolonia_api
.get_city_master(prefecture.name_ja(), &city_name)
.await
{
Ok(result) => result,
Err(error) => {
if self.options.verbose {
log::error!("{}", error.error_message)
}
return tokenizer.finish().tokens;
}
};
let (_, tokenizer) =
match tokenizer.read_town(city_master.towns.iter().map(|x| x.name.clone()).collect()) {
Ok(found) => found,
Err(not_found) => {
if self.options.verbose {
log::error!("町名の検出に失敗しました")
}
return not_found.tokens;
}
};

tokenizer.finish().tokens
}
}

#[cfg(test)]
mod tests {
use crate::domain::common::token::{City, Prefecture, Token, Town};
use crate::experimental::parser::{DataSource, Parser, ParserOptions};

#[tokio::test]
async fn 都道府県名が誤っている場合() {
let parser = Parser {
options: ParserOptions {
data_source: DataSource::Geolonia,
correct_incomplete_city_names: false,
verbose: false,
},
};
let result = parser
.parse_with_geolonia("奈川県横浜市磯子区洋光台3-10-3")
.await;
assert_eq!(
result,
vec![Token::Rest("奈川県横浜市磯子区洋光台3-10-3".to_string())]
)
}

#[tokio::test]
async fn 市区町村名が誤っている場合() {
let parser = Parser {
options: ParserOptions {
data_source: DataSource::Geolonia,
correct_incomplete_city_names: false,
verbose: false,
},
};
let result = parser
.parse_with_geolonia("神奈川県横浜県磯子市洋光台3-10-3")
.await;
assert_eq!(
result,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
representative_point: None,
}),
Token::Rest("横浜県磯子市洋光台3-10-3".to_string())
]
)
}

#[tokio::test]
async fn 町名が誤っている場合() {
let parser = Parser {
options: ParserOptions {
data_source: DataSource::Geolonia,
correct_incomplete_city_names: false,
verbose: false,
},
};
let result = parser
.parse_with_geolonia("神奈川県横浜市磯子区陽光台3-10-3")
.await;
assert_eq!(
result,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
representative_point: None,
}),
Token::City(City {
city_name: "横浜市磯子区".to_string(),
representative_point: None,
}),
Token::Rest("陽光台3-10-3".to_string())
]
)
}

#[tokio::test]
async fn パースに成功した場合() {
let parser = Parser {
options: ParserOptions {
data_source: DataSource::Geolonia,
correct_incomplete_city_names: false,
verbose: false,
},
};
let result = parser
.parse_with_geolonia("神奈川県横浜市磯子区洋光台3-10-3")
.await;
assert_eq!(
result,
vec![
Token::Prefecture(Prefecture {
prefecture_name: "神奈川県".to_string(),
representative_point: None,
}),
Token::City(City {
city_name: "横浜市磯子区".to_string(),
representative_point: None,
}),
Token::Town(Town {
town_name: "洋光台三丁目".to_string(),
representative_point: None,
}),
Token::Rest("10-3".to_string())
]
)
}
}
Loading
Loading