From 1c1880dfb1ef98a01dda685f9cea9f2e3a923a53 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:26:01 +0900 Subject: [PATCH 01/38] =?UTF-8?q?add:=20#426:=20`domain::chimei=5Fruiju`?= =?UTF-8?q?=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/domain.rs | 1 + core/src/domain/chimei_ruiju.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 core/src/domain/chimei_ruiju.rs diff --git a/core/src/domain.rs b/core/src/domain.rs index bb3a487a..9df7829d 100644 --- a/core/src/domain.rs +++ b/core/src/domain.rs @@ -1 +1,2 @@ +pub mod chimei_ruiju; pub mod geolonia; diff --git a/core/src/domain/chimei_ruiju.rs b/core/src/domain/chimei_ruiju.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/core/src/domain/chimei_ruiju.rs @@ -0,0 +1 @@ + From 6113016ce218883fb465fe9628759be9bba7338d Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:30:00 +0900 Subject: [PATCH 02/38] =?UTF-8?q?add:=20#426:=20chimei-ruiju.org=E7=94=A8?= =?UTF-8?q?=E3=81=AE=E3=82=A8=E3=83=B3=E3=83=86=E3=82=A3=E3=83=86=E3=82=A3?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/domain/chimei_ruiju.rs | 2 +- core/src/domain/chimei_ruiju/entity.rs | 51 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 core/src/domain/chimei_ruiju/entity.rs diff --git a/core/src/domain/chimei_ruiju.rs b/core/src/domain/chimei_ruiju.rs index 8b137891..e8c3d6a4 100644 --- a/core/src/domain/chimei_ruiju.rs +++ b/core/src/domain/chimei_ruiju.rs @@ -1 +1 @@ - +pub mod entity; diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs new file mode 100644 index 00000000..1bc4e184 --- /dev/null +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -0,0 +1,51 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug)] +pub struct PrefectureMaster { + /// 都道府県名 + pub(crate) name: String, + /// 市区町村名リスト + pub(crate) cities: Vec, + /// 代表点の緯度経度 + pub(crate) coordinate: Coordinate, +} + +#[derive(Deserialize, Debug)] +pub struct CityMaster { + /// 市区町村名 + name: String, + /// 町名リスト + towns: Vec, + /// 緯度経度 + coordinate: Coordinate, +} + +#[derive(Deserialize, Debug)] +pub struct TownMaster { + /// 町名 + name: String, + /// 街区リスト + blocks: Vec, + /// 緯度経度 + coordinate: Coordinate, +} + +#[derive(Deserialize, Debug)] +pub struct Block { + /// 小字・通称名 + koaza: String, + /// 街区符号・地番 + block_number: String, + /// 住居表示の有無 + residential_address_indication: bool, + /// 緯度経度 + coordinate: Coordinate, +} + +#[derive(Deserialize, Debug)] +pub struct Coordinate { + /// 緯度 + pub(crate) latitude: f64, + /// 経度 + pub(crate) longitude: f64, +} From 9d2b323d127076deb1b1d498ae30f2fc13947ce8 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:34:14 +0900 Subject: [PATCH 03/38] =?UTF-8?q?add:=20#426:=20chimei-ruiju.org=E3=81=AE?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E7=94=A8enum=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Cargo.toml | 1 + core/src/domain/chimei_ruiju.rs | 1 + core/src/domain/chimei_ruiju/error.rs | 11 +++++++++++ 3 files changed, 13 insertions(+) create mode 100644 core/src/domain/chimei_ruiju/error.rs diff --git a/core/Cargo.toml b/core/Cargo.toml index 0e72ca7d..d14fc9bf 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -28,6 +28,7 @@ regex = "1.10.2" serde.workspace = true reqwest = { version = "0.12.5", default-features = false, features = ["json", "rustls-tls"] } js-sys = "0.3.67" +thiserror = "1.0.63" [dev-dependencies] tokio.workspace = true diff --git a/core/src/domain/chimei_ruiju.rs b/core/src/domain/chimei_ruiju.rs index e8c3d6a4..c5cd99ae 100644 --- a/core/src/domain/chimei_ruiju.rs +++ b/core/src/domain/chimei_ruiju.rs @@ -1 +1,2 @@ pub mod entity; +pub mod error; diff --git a/core/src/domain/chimei_ruiju/error.rs b/core/src/domain/chimei_ruiju/error.rs new file mode 100644 index 00000000..6418132f --- /dev/null +++ b/core/src/domain/chimei_ruiju/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Error, PartialEq, Debug)] +pub enum ApiError { + #[error("network error occurs: {url}")] + Network { url: String }, + #[error("resource not found: {url}")] + NotFound { url: String }, + #[error("deserialize error occurs: {url}")] + Deserialize { url: String }, +} From 9fd9d943479e699079024926e7761ab231681d30 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:44:54 +0900 Subject: [PATCH 04/38] =?UTF-8?q?add:=20#426:=20`service::chimei=5Fruiju`?= =?UTF-8?q?=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/service.rs | 1 + core/src/service/chimei_ruiju.rs | 0 2 files changed, 1 insertion(+) create mode 100644 core/src/service/chimei_ruiju.rs diff --git a/core/src/service.rs b/core/src/service.rs index bb3a487a..9df7829d 100644 --- a/core/src/service.rs +++ b/core/src/service.rs @@ -1 +1,2 @@ +pub mod chimei_ruiju; pub mod geolonia; diff --git a/core/src/service/chimei_ruiju.rs b/core/src/service/chimei_ruiju.rs new file mode 100644 index 00000000..e69de29b From 62d94d06c93587a880498ef7f57d92402ba075ec Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:45:22 +0900 Subject: [PATCH 05/38] =?UTF-8?q?add:=20#426:=20`ChimeiRuijuApiService`?= =?UTF-8?q?=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/service/chimei_ruiju.rs | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/core/src/service/chimei_ruiju.rs b/core/src/service/chimei_ruiju.rs index e69de29b..e6d4c9d9 100644 --- a/core/src/service/chimei_ruiju.rs +++ b/core/src/service/chimei_ruiju.rs @@ -0,0 +1,47 @@ +use crate::domain::chimei_ruiju::error::ApiError; +use reqwest::StatusCode; +use serde::de::DeserializeOwned; + +pub struct ChimeiRuijuApiService {} + +impl ChimeiRuijuApiService { + pub async fn get(&self, url: &str) -> Result + where + T: DeserializeOwned, + { + let response = reqwest::get(url).await.map_err(|_| ApiError::Network { + url: url.to_string(), + })?; + if response.status() == StatusCode::NOT_FOUND { + return Err(ApiError::NotFound { + url: url.to_string(), + }); + } + response + .json::() + .await + .map_err(|_| ApiError::Deserialize { + url: url.to_string(), + }) + } +} + +#[cfg(feature = "blocking")] +impl ChimeiRuijuApiService { + pub fn get_blocking(&self, url: &str) -> Result + where + T: DeserializeOwned, + { + let response = reqwest::blocking::get(url).map_err(|_| ApiError::Network { + url: url.to_string(), + })?; + if response.status() == StatusCode::NOT_FOUND { + return Err(ApiError::NotFound { + url: url.to_string(), + }); + } + response.json::().map_err(|_| ApiError::Deserialize { + url: url.to_string(), + }) + } +} From ecf9427cbf93c2962b11146feecc0e667178d5cd Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 16:48:24 +0900 Subject: [PATCH 06/38] =?UTF-8?q?add:=20#426:=20`ChimeiRuijuApiService`?= =?UTF-8?q?=E3=81=AB=E5=AF=BE=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/service/chimei_ruiju.rs | 174 +++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/core/src/service/chimei_ruiju.rs b/core/src/service/chimei_ruiju.rs index e6d4c9d9..24ab29d5 100644 --- a/core/src/service/chimei_ruiju.rs +++ b/core/src/service/chimei_ruiju.rs @@ -45,3 +45,177 @@ impl ChimeiRuijuApiService { }) } } + +#[cfg(all(test, not(target_arch = "wasm32")))] +mod async_tests { + use crate::domain::chimei_ruiju::entity::PrefectureMaster; + use crate::domain::chimei_ruiju::error::ApiError; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + + #[tokio::test] + async fn 失敗_ネットワークエラー() { + let invalid_url = "htttp://chimei-ruiju.org"; + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get::(invalid_url).await; + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!( + error, + ApiError::Network { + url: invalid_url.to_string(), + } + ); + } + + #[tokio::test] + async fn 失敗_404エラー() { + let mut server = mockito::Server::new_async().await; + let url = format!("{}/master.json", &server.url()); + let mock = server + .mock("GET", "/master.json") + .with_status(404) + .create_async() + .await; + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get::(&url).await; + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!(error, ApiError::NotFound { url: url.clone() }); + + mock.assert_async().await; + } + + #[tokio::test] + async fn 失敗_デシリアライズエラー() { + let mut server = mockito::Server::new_async().await; + let url = format!("{}/master.json", &server.url()); + let mock = server + .mock("GET", "/master.json") + .with_status(200) + .with_header("content-type", "application/json") + .with_body(r#"{"hoge": true, "piyo": 100}"#) + .create_async() + .await; + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get::(&url).await; + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!(error, ApiError::Deserialize { url: url.clone() }); + + mock.assert_async().await; + } + + #[tokio::test] + async fn 成功() { + let mut server = mockito::Server::new_async().await; + let url = format!("{}/master.json", &server.url()); + let mock = server + .mock("GET", "/master.json") + .with_status(200) + .with_header("content-type", "application/json") + .with_body(r#"{"name": "新浜県", "cities": ["新浜市"], "coordinate": {"latitude": 34.6570413, "longitude": 135.2741341}}"#) + .create_async() + .await; + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get::(&url).await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "新浜県"); + assert_eq!(entity.cities, vec!["新浜市"]); + assert_eq!(entity.coordinate.latitude, 34.6570413); + assert_eq!(entity.coordinate.longitude, 135.2741341); + + mock.assert_async().await; + } +} + +#[cfg(all(test, feature = "blocking", not(target_arch = "wasm32")))] +mod blocking_tests { + use crate::domain::chimei_ruiju::entity::PrefectureMaster; + use crate::domain::chimei_ruiju::error::ApiError; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + + #[test] + fn 失敗_ネットワークエラー() { + let invalid_url = "htttp://chimei-ruiju.org"; + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get_blocking::(invalid_url); + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!( + error, + ApiError::Network { + url: invalid_url.to_string(), + } + ); + } + + #[test] + fn 失敗_404エラー() { + let mut server = mockito::Server::new(); + let url = format!("{}/master.json", &server.url()); + let mock = server.mock("GET", "/master.json").with_status(404).create(); + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get_blocking::(&url); + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!(error, ApiError::NotFound { url: url.clone() }); + + mock.assert(); + } + + #[test] + fn 失敗_デシリアライズエラー() { + let mut server = mockito::Server::new(); + let url = format!("{}/master.json", &server.url()); + let mock = server + .mock("GET", "/master.json") + .with_status(200) + .with_header("content-type", "application/json") + .with_body(r#"{"hoge": true, "piyo": 100}"#) + .create(); + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get_blocking::(&url); + assert!(result.is_err()); + let error = result.unwrap_err(); + assert_eq!(error, ApiError::Deserialize { url: url.clone() }); + + mock.assert(); + } + + #[test] + fn 成功() { + let mut server = mockito::Server::new(); + let url = format!("{}/master.json", &server.url()); + let mock = server + .mock("GET", "/master.json") + .with_status(200) + .with_header("content-type", "application/json") + .with_body(r#"{"name": "新浜県", "cities": ["新浜市"], "coordinate": {"latitude": 34.6570413, "longitude": 135.2741341}}"#) + .create(); + + let api_service = ChimeiRuijuApiService {}; + + let result = api_service.get_blocking::(&url); + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "新浜県"); + assert_eq!(entity.cities, vec!["新浜市"]); + assert_eq!(entity.coordinate.latitude, 34.6570413); + assert_eq!(entity.coordinate.longitude, 135.2741341); + + mock.assert(); + } +} From 616cdeab5a042b9d7ab15c889646cf8575c51869 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 17:26:49 +0900 Subject: [PATCH 07/38] =?UTF-8?q?add:=20#426:=20`repository::chimei=5Fruij?= =?UTF-8?q?u`=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=82=92?= =?UTF-8?q?=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/repository.rs | 1 + core/src/repository/chimei_ruiju.rs | 0 2 files changed, 1 insertion(+) create mode 100644 core/src/repository/chimei_ruiju.rs diff --git a/core/src/repository.rs b/core/src/repository.rs index bb3a487a..9df7829d 100644 --- a/core/src/repository.rs +++ b/core/src/repository.rs @@ -1 +1,2 @@ +pub mod chimei_ruiju; pub mod geolonia; diff --git a/core/src/repository/chimei_ruiju.rs b/core/src/repository/chimei_ruiju.rs new file mode 100644 index 00000000..e69de29b From 4fb79eda4b2d1770f1d89d70a650c4819822dec9 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 17:31:26 +0900 Subject: [PATCH 08/38] =?UTF-8?q?add:=20#426:=20`PrefectureMasterRepositor?= =?UTF-8?q?y`=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/Cargo.toml | 1 + core/src/repository/chimei_ruiju.rs | 1 + .../src/repository/chimei_ruiju/prefecture.rs | 238 ++++++++++++++++++ 3 files changed, 240 insertions(+) create mode 100644 core/src/repository/chimei_ruiju/prefecture.rs diff --git a/core/Cargo.toml b/core/Cargo.toml index d14fc9bf..6141dd87 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -29,6 +29,7 @@ serde.workspace = true reqwest = { version = "0.12.5", default-features = false, features = ["json", "rustls-tls"] } js-sys = "0.3.67" thiserror = "1.0.63" +jisx0401 = "0.1.0-beta.2" [dev-dependencies] tokio.workspace = true diff --git a/core/src/repository/chimei_ruiju.rs b/core/src/repository/chimei_ruiju.rs index e69de29b..4d06d7ba 100644 --- a/core/src/repository/chimei_ruiju.rs +++ b/core/src/repository/chimei_ruiju.rs @@ -0,0 +1 @@ +pub mod prefecture; diff --git a/core/src/repository/chimei_ruiju/prefecture.rs b/core/src/repository/chimei_ruiju/prefecture.rs new file mode 100644 index 00000000..702cb0d9 --- /dev/null +++ b/core/src/repository/chimei_ruiju/prefecture.rs @@ -0,0 +1,238 @@ +use crate::domain::chimei_ruiju::entity::PrefectureMaster; +use crate::domain::chimei_ruiju::error::ApiError; +use crate::service::chimei_ruiju::ChimeiRuijuApiService; +use jisx0401::Prefecture; + +pub struct PrefectureMasterRepository { + api_service: ChimeiRuijuApiService, +} + +impl PrefectureMasterRepository { + pub async fn get(&self, prefecture: &Prefecture) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/master.json", + prefecture.name_en() + ); + self.api_service.get::(&url).await + } +} + +#[cfg(test)] +mod async_tests { + use crate::repository::chimei_ruiju::prefecture::PrefectureMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[tokio::test] + async fn 東京都() { + let repository = PrefectureMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::TOKYO).await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "東京都"); + assert_eq!( + entity.cities, + vec![ + "千代田区", + "中央区", + "港区", + "新宿区", + "文京区", + "台東区", + "墨田区", + "江東区", + "品川区", + "目黒区", + "大田区", + "世田谷区", + "渋谷区", + "中野区", + "杉並区", + "豊島区", + "北区", + "荒川区", + "板橋区", + "練馬区", + "足立区", + "葛飾区", + "江戸川区", + "八王子市", + "立川市", + "武蔵野市", + "三鷹市", + "青梅市", + "府中市", + "昭島市", + "調布市", + "町田市", + "小金井市", + "小平市", + "日野市", + "東村山市", + "国分寺市", + "国立市", + "福生市", + "狛江市", + "東大和市", + "清瀬市", + "東久留米市", + "武蔵村山市", + "多摩市", + "稲城市", + "羽村市", + "あきる野市", + "西東京市", + "西多摩郡瑞穂町", + "西多摩郡日の出町", + "西多摩郡檜原村", + "西多摩郡奥多摩町", + "大島町", + "利島村", + "新島村", + "神津島村", + "三宅村", + "御蔵島村", + "八丈町", + "青ヶ島村", + "小笠原村", + ] + ) + } + + #[tokio::test] + async fn 富山県() { + let repository = PrefectureMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::TOYAMA).await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "富山県"); + assert_eq!( + entity.cities, + vec![ + "富山市", + "高岡市", + "魚津市", + "氷見市", + "滑川市", + "黒部市", + "砺波市", + "小矢部市", + "南砺市", + "射水市", + "中新川郡舟橋村", + "中新川郡上市町", + "中新川郡立山町", + "下新川郡入善町", + "下新川郡朝日町", + ] + ); + } +} + +#[cfg(feature = "blocking")] +impl PrefectureMasterRepository { + pub fn get_blocking(&self, prefecture: Prefecture) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/master.json", + prefecture.name_en() + ); + self.api_service.get_blocking::(&url) + } +} + +#[cfg(all(test, feature = "blocking"))] +mod blocking_tests { + use crate::repository::chimei_ruiju::prefecture::PrefectureMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[tokio::test] + async fn 高知県() { + let repository = PrefectureMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::KOCHI).await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "高知県"); + assert_eq!( + entity.cities, + vec![ + "高知市", + "室戸市", + "安芸市", + "南国市", + "土佐市", + "須崎市", + "宿毛市", + "土佐清水市", + "四万十市", + "香南市", + "香美市", + "安芸郡東洋町", + "安芸郡奈半利町", + "安芸郡田野町", + "安芸郡安田町", + "安芸郡北川村", + "安芸郡馬路村", + "安芸郡芸西村", + "長岡郡本山町", + "長岡郡大豊町", + "土佐郡土佐町", + "土佐郡大川村", + "吾川郡いの町", + "吾川郡仁淀川町", + "高岡郡中土佐町", + "高岡郡佐川町", + "高岡郡越知町", + "高岡郡檮原町", + "高岡郡日高村", + "高岡郡津野町", + "高岡郡四万十町", + "幡多郡大月町", + "幡多郡三原村", + "幡多郡黒潮町" + ] + ) + } + + #[tokio::test] + async fn 佐賀県() { + let repository = PrefectureMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::SAGA).await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "佐賀県"); + assert_eq!( + entity.cities, + vec![ + "佐賀市", + "唐津市", + "鳥栖市", + "多久市", + "伊万里市", + "武雄市", + "鹿島市", + "小城市", + "嬉野市", + "神埼市", + "神埼郡吉野ヶ里町", + "三養基郡基山町", + "三養基郡上峰町", + "三養基郡みやき町", + "東松浦郡玄海町", + "西松浦郡有田町", + "杵島郡大町町", + "杵島郡江北町", + "杵島郡白石町", + "藤津郡太良町" + ] + ); + } +} From 9bdb92fd089a19abd145c8e87151ee58c3149fa2 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 17:34:44 +0900 Subject: [PATCH 09/38] =?UTF-8?q?add:=20#426:=20`CityMasterRepository`?= =?UTF-8?q?=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/domain/chimei_ruiju/entity.rs | 4 +- core/src/repository/chimei_ruiju.rs | 1 + core/src/repository/chimei_ruiju/city.rs | 138 +++++++++++++++++++++++ 3 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 core/src/repository/chimei_ruiju/city.rs diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs index 1bc4e184..e20a0b3d 100644 --- a/core/src/domain/chimei_ruiju/entity.rs +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -13,9 +13,9 @@ pub struct PrefectureMaster { #[derive(Deserialize, Debug)] pub struct CityMaster { /// 市区町村名 - name: String, + pub(crate) name: String, /// 町名リスト - towns: Vec, + pub(crate) towns: Vec, /// 緯度経度 coordinate: Coordinate, } diff --git a/core/src/repository/chimei_ruiju.rs b/core/src/repository/chimei_ruiju.rs index 4d06d7ba..650ab236 100644 --- a/core/src/repository/chimei_ruiju.rs +++ b/core/src/repository/chimei_ruiju.rs @@ -1 +1,2 @@ +pub mod city; pub mod prefecture; diff --git a/core/src/repository/chimei_ruiju/city.rs b/core/src/repository/chimei_ruiju/city.rs new file mode 100644 index 00000000..2d09d70a --- /dev/null +++ b/core/src/repository/chimei_ruiju/city.rs @@ -0,0 +1,138 @@ +use crate::domain::chimei_ruiju::entity::CityMaster; +use crate::domain::chimei_ruiju::error::ApiError; +use crate::service::chimei_ruiju::ChimeiRuijuApiService; +use jisx0401::Prefecture; + +pub struct CityMasterRepository { + api_service: ChimeiRuijuApiService, +} + +impl CityMasterRepository { + pub async fn get( + &self, + prefecture: &Prefecture, + city_name: &str, + ) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/{}/master.json", + prefecture.name_en(), + city_name + ); + self.api_service.get::(&url).await + } +} + +#[cfg(test)] +mod async_tests { + use crate::repository::chimei_ruiju::city::CityMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[tokio::test] + async fn 神奈川県愛甲郡清川村() { + let repository = CityMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::KANAGAWA, "愛甲郡清川村").await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "愛甲郡清川村"); + assert_eq!(entity.towns, vec!["煤ヶ谷", "宮ヶ瀬"]); + } + + #[tokio::test] + async fn 京都府乙訓郡大山崎町() { + let repository = CityMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get(&Prefecture::KYOTO, "乙訓郡大山崎町").await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "乙訓郡大山崎町"); + assert_eq!(entity.towns, vec!["字円明寺", "字大山崎", "字下植野"]); + } +} + +#[cfg(feature = "blocking")] +impl CityMasterRepository { + pub fn get_blocking( + &self, + prefecture: &Prefecture, + city_name: &str, + ) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/{}/master.json", + prefecture.name_en(), + city_name + ); + self.api_service.get_blocking::(&url) + } +} + +#[cfg(all(test, feature = "blocking"))] +mod blocking_tests { + use crate::repository::chimei_ruiju::city::CityMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[test] + fn 埼玉県比企郡嵐山町() { + let repository = CityMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get_blocking(&Prefecture::SAITAMA, "比企郡嵐山町"); + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "比企郡嵐山町"); + assert_eq!( + entity.towns, + vec![ + "むさし台一丁目", + "むさし台二丁目", + "むさし台三丁目", + "大字根岸", + "大字勝田", + "大字太郎丸", + "大字川島", + "花見台", + "大字遠山", + "大字大蔵", + "大字菅谷", + "大字千手堂", + "大字廣野", + "大字杉山", + "大字平澤", + "大字将軍澤", + "大字志賀", + "大字吉田", + "大字古里", + "大字越畑", + "大字鎌形" + ] + ); + } + + #[test] + fn 岐阜県不破郡関ケ原町() { + let repository = CityMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get_blocking(&Prefecture::GIFU, "不破郡関ケ原町"); + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "不破郡関ケ原町"); + assert_eq!( + entity.towns, + vec![ + "大字今須", + "大字大高", + "大字関ケ原", + "大字玉", + "大字藤下", + "大字野上", + "大字松尾", + "大字山中" + ] + ); + } +} From 70195dc48ec1357381dd8431fe86da08bfe41bb3 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 17:37:48 +0900 Subject: [PATCH 10/38] =?UTF-8?q?add:=20#426:=20`TownMasterRepository`?= =?UTF-8?q?=E3=82=92=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 当面は使用されないので`#[allow(dead_code)]`を付与しておく --- core/src/domain/chimei_ruiju/entity.rs | 2 +- core/src/repository/chimei_ruiju.rs | 1 + core/src/repository/chimei_ruiju/town.rs | 82 ++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 core/src/repository/chimei_ruiju/town.rs diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs index e20a0b3d..1d793d27 100644 --- a/core/src/domain/chimei_ruiju/entity.rs +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -23,7 +23,7 @@ pub struct CityMaster { #[derive(Deserialize, Debug)] pub struct TownMaster { /// 町名 - name: String, + pub(crate) name: String, /// 街区リスト blocks: Vec, /// 緯度経度 diff --git a/core/src/repository/chimei_ruiju.rs b/core/src/repository/chimei_ruiju.rs index 650ab236..5c4bae46 100644 --- a/core/src/repository/chimei_ruiju.rs +++ b/core/src/repository/chimei_ruiju.rs @@ -1,2 +1,3 @@ pub mod city; pub mod prefecture; +mod town; diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs new file mode 100644 index 00000000..71b09122 --- /dev/null +++ b/core/src/repository/chimei_ruiju/town.rs @@ -0,0 +1,82 @@ +use crate::domain::chimei_ruiju::entity::TownMaster; +use crate::domain::chimei_ruiju::error::ApiError; +use crate::service::chimei_ruiju::ChimeiRuijuApiService; +use jisx0401::Prefecture; + +#[allow(dead_code)] +pub struct TownMasterRepository { + api_service: ChimeiRuijuApiService, +} + +impl TownMasterRepository { + pub async fn get( + &self, + prefecture: &Prefecture, + city_name: &str, + town_name: &str, + ) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/{}/{}/master.json", + prefecture.name_en(), + city_name, + town_name + ); + self.api_service.get::(&url).await + } +} + +#[cfg(test)] +mod async_tests { + use crate::repository::chimei_ruiju::town::TownMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[tokio::test] + async fn 東京都千代田区千代田() { + let repository = TownMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository + .get(&Prefecture::TOKYO, "千代田区", "千代田") + .await; + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "千代田"); + } +} + +#[cfg(feature = "blocking")] +impl TownMasterRepository { + pub fn get_blocking( + &self, + prefecture: &Prefecture, + city_name: &str, + town_name: &str, + ) -> Result { + let url = format!( + "https://{}.chimei-ruiju.org/{}/{}/master.json", + prefecture.name_en(), + city_name, + town_name + ); + self.api_service.get_blocking::(&url) + } +} + +#[cfg(all(test, feature = "blocking"))] +mod blocking_tests { + use crate::repository::chimei_ruiju::town::TownMasterRepository; + use crate::service::chimei_ruiju::ChimeiRuijuApiService; + use jisx0401::Prefecture; + + #[test] + fn 京都府京都市伏見区魚屋町() { + let repository = TownMasterRepository { + api_service: ChimeiRuijuApiService {}, + }; + let result = repository.get_blocking(&Prefecture::KYOTO, "京都市伏見区", "魚屋町"); + assert!(result.is_ok()); + let entity = result.unwrap(); + assert_eq!(entity.name, "魚屋町"); + } +} From d7b5567f752400268b53967069e09fd33727b1c1 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 21:56:46 +0900 Subject: [PATCH 11/38] =?UTF-8?q?update:=20#426:=20`PrefectureMasterReposi?= =?UTF-8?q?tory#get`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=8B?= =?UTF-8?q?=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- .../src/repository/chimei_ruiju/prefecture.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/core/src/repository/chimei_ruiju/prefecture.rs b/core/src/repository/chimei_ruiju/prefecture.rs index 702cb0d9..a369c3e1 100644 --- a/core/src/repository/chimei_ruiju/prefecture.rs +++ b/core/src/repository/chimei_ruiju/prefecture.rs @@ -8,12 +8,15 @@ pub struct PrefectureMasterRepository { } impl PrefectureMasterRepository { - pub async fn get(&self, prefecture: &Prefecture) -> Result { + pub async fn get( + api_service: &ChimeiRuijuApiService, + prefecture: &Prefecture, + ) -> Result { let url = format!( "https://{}.chimei-ruiju.org/master.json", prefecture.name_en() ); - self.api_service.get::(&url).await + api_service.get::(&url).await } } @@ -25,10 +28,8 @@ mod async_tests { #[tokio::test] async fn 東京都() { - let repository = PrefectureMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::TOKYO).await; + let api_service = ChimeiRuijuApiService {}; + let result = PrefectureMasterRepository::get(&api_service, &Prefecture::TOKYO).await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "東京都"); @@ -103,10 +104,8 @@ mod async_tests { #[tokio::test] async fn 富山県() { - let repository = PrefectureMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::TOYAMA).await; + let api_service = ChimeiRuijuApiService {}; + let result = PrefectureMasterRepository::get(&api_service, &Prefecture::TOYAMA).await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "富山県"); From 493657e79ddd0f28e9bf142a4bafaf99908e6ae5 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 21:57:05 +0900 Subject: [PATCH 12/38] =?UTF-8?q?update:=20#426:=20`PrefectureMasterReposi?= =?UTF-8?q?tory#get=5Fblocking`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=81=8B=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- .../src/repository/chimei_ruiju/prefecture.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/core/src/repository/chimei_ruiju/prefecture.rs b/core/src/repository/chimei_ruiju/prefecture.rs index a369c3e1..294481cc 100644 --- a/core/src/repository/chimei_ruiju/prefecture.rs +++ b/core/src/repository/chimei_ruiju/prefecture.rs @@ -134,12 +134,15 @@ mod async_tests { #[cfg(feature = "blocking")] impl PrefectureMasterRepository { - pub fn get_blocking(&self, prefecture: Prefecture) -> Result { + pub fn get_blocking( + api_service: &ChimeiRuijuApiService, + prefecture: Prefecture, + ) -> Result { let url = format!( "https://{}.chimei-ruiju.org/master.json", prefecture.name_en() ); - self.api_service.get_blocking::(&url) + api_service.get_blocking::(&url) } } @@ -151,10 +154,8 @@ mod blocking_tests { #[tokio::test] async fn 高知県() { - let repository = PrefectureMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::KOCHI).await; + let api_service = ChimeiRuijuApiService {}; + let result = PrefectureMasterRepository::get(&api_service, &Prefecture::KOCHI).await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "高知県"); @@ -201,10 +202,8 @@ mod blocking_tests { #[tokio::test] async fn 佐賀県() { - let repository = PrefectureMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::SAGA).await; + let api_service = ChimeiRuijuApiService {}; + let result = PrefectureMasterRepository::get(&api_service, &Prefecture::SAGA).await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "佐賀県"); From 018e23bdad8fa8b4880aa1f35d49c3c2f6c0d573 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 21:57:44 +0900 Subject: [PATCH 13/38] =?UTF-8?q?update:=20#426:=20=E6=A7=8B=E9=80=A0?= =?UTF-8?q?=E4=BD=93`PrefectureMasterRepository`=E3=81=8B=E3=82=89?= =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB=E3=83=89`api=5Fservice`?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/repository/chimei_ruiju/prefecture.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/repository/chimei_ruiju/prefecture.rs b/core/src/repository/chimei_ruiju/prefecture.rs index 294481cc..48269e20 100644 --- a/core/src/repository/chimei_ruiju/prefecture.rs +++ b/core/src/repository/chimei_ruiju/prefecture.rs @@ -3,9 +3,7 @@ use crate::domain::chimei_ruiju::error::ApiError; use crate::service::chimei_ruiju::ChimeiRuijuApiService; use jisx0401::Prefecture; -pub struct PrefectureMasterRepository { - api_service: ChimeiRuijuApiService, -} +pub struct PrefectureMasterRepository {} impl PrefectureMasterRepository { pub async fn get( From 91978c802f5fa37834fec8a29d82cc73a109696b Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:48:26 +0900 Subject: [PATCH 14/38] =?UTF-8?q?update:=20#426:=20`CityMasterRepository#g?= =?UTF-8?q?et`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=8B?= =?UTF-8?q?=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- core/src/repository/chimei_ruiju/city.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/core/src/repository/chimei_ruiju/city.rs b/core/src/repository/chimei_ruiju/city.rs index 2d09d70a..ce12380d 100644 --- a/core/src/repository/chimei_ruiju/city.rs +++ b/core/src/repository/chimei_ruiju/city.rs @@ -9,7 +9,7 @@ pub struct CityMasterRepository { impl CityMasterRepository { pub async fn get( - &self, + api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, city_name: &str, ) -> Result { @@ -18,7 +18,7 @@ impl CityMasterRepository { prefecture.name_en(), city_name ); - self.api_service.get::(&url).await + api_service.get::(&url).await } } @@ -30,10 +30,9 @@ mod async_tests { #[tokio::test] async fn 神奈川県愛甲郡清川村() { - let repository = CityMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::KANAGAWA, "愛甲郡清川村").await; + let api_service = ChimeiRuijuApiService {}; + let result = + CityMasterRepository::get(&api_service, &Prefecture::KANAGAWA, "愛甲郡清川村").await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "愛甲郡清川村"); @@ -42,10 +41,9 @@ mod async_tests { #[tokio::test] async fn 京都府乙訓郡大山崎町() { - let repository = CityMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get(&Prefecture::KYOTO, "乙訓郡大山崎町").await; + let api_service = ChimeiRuijuApiService {}; + let result = + CityMasterRepository::get(&api_service, &Prefecture::KYOTO, "乙訓郡大山崎町").await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "乙訓郡大山崎町"); From 45b307b895093f981d9e7269d9b46c429ab92da2 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:50:01 +0900 Subject: [PATCH 15/38] =?UTF-8?q?update:=20#426:=20`CityMasterRepository#g?= =?UTF-8?q?et=5Fblocking`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=8B=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- core/src/repository/chimei_ruiju/city.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/core/src/repository/chimei_ruiju/city.rs b/core/src/repository/chimei_ruiju/city.rs index ce12380d..9e9ce3bf 100644 --- a/core/src/repository/chimei_ruiju/city.rs +++ b/core/src/repository/chimei_ruiju/city.rs @@ -54,7 +54,7 @@ mod async_tests { #[cfg(feature = "blocking")] impl CityMasterRepository { pub fn get_blocking( - &self, + api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, city_name: &str, ) -> Result { @@ -63,7 +63,7 @@ impl CityMasterRepository { prefecture.name_en(), city_name ); - self.api_service.get_blocking::(&url) + api_service.get_blocking::(&url) } } @@ -75,10 +75,9 @@ mod blocking_tests { #[test] fn 埼玉県比企郡嵐山町() { - let repository = CityMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get_blocking(&Prefecture::SAITAMA, "比企郡嵐山町"); + let api_service = ChimeiRuijuApiService {}; + let result = + CityMasterRepository::get_blocking(&api_service, &Prefecture::SAITAMA, "比企郡嵐山町"); assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "比企郡嵐山町"); @@ -112,10 +111,9 @@ mod blocking_tests { #[test] fn 岐阜県不破郡関ケ原町() { - let repository = CityMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get_blocking(&Prefecture::GIFU, "不破郡関ケ原町"); + let api_service = ChimeiRuijuApiService {}; + let result = + CityMasterRepository::get_blocking(&api_service, &Prefecture::GIFU, "不破郡関ケ原町"); assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "不破郡関ケ原町"); From 41ed3f2704ecbcf023c4c6b3311fd73a6510aa8e Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:50:44 +0900 Subject: [PATCH 16/38] =?UTF-8?q?update:=20#426:=20=E6=A7=8B=E9=80=A0?= =?UTF-8?q?=E4=BD=93`CityMasterRepository`=E3=81=8B=E3=82=89=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=83=BC=E3=83=AB=E3=83=89`api=5Fservice`=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/repository/chimei_ruiju/city.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/repository/chimei_ruiju/city.rs b/core/src/repository/chimei_ruiju/city.rs index 9e9ce3bf..a788390c 100644 --- a/core/src/repository/chimei_ruiju/city.rs +++ b/core/src/repository/chimei_ruiju/city.rs @@ -3,9 +3,7 @@ use crate::domain::chimei_ruiju::error::ApiError; use crate::service::chimei_ruiju::ChimeiRuijuApiService; use jisx0401::Prefecture; -pub struct CityMasterRepository { - api_service: ChimeiRuijuApiService, -} +pub struct CityMasterRepository {} impl CityMasterRepository { pub async fn get( From bac787859a334c9ca0f4d2abcf12e809b96b7eb6 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:53:02 +0900 Subject: [PATCH 17/38] =?UTF-8?q?update:=20#426:=20`TownMasterRepository#g?= =?UTF-8?q?et`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=8B?= =?UTF-8?q?=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- core/src/repository/chimei_ruiju/town.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs index 71b09122..4ce1eb22 100644 --- a/core/src/repository/chimei_ruiju/town.rs +++ b/core/src/repository/chimei_ruiju/town.rs @@ -10,7 +10,7 @@ pub struct TownMasterRepository { impl TownMasterRepository { pub async fn get( - &self, + api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, city_name: &str, town_name: &str, @@ -21,7 +21,7 @@ impl TownMasterRepository { city_name, town_name ); - self.api_service.get::(&url).await + api_service.get::(&url).await } } @@ -33,12 +33,9 @@ mod async_tests { #[tokio::test] async fn 東京都千代田区千代田() { - let repository = TownMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository - .get(&Prefecture::TOKYO, "千代田区", "千代田") - .await; + let api_service = ChimeiRuijuApiService {}; + let result = + TownMasterRepository::get(&api_service, &Prefecture::TOKYO, "千代田区", "千代田").await; assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "千代田"); From 890b4d65fb5df2e8c09da9c6dcda7ce05c89e9fb Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:54:31 +0900 Subject: [PATCH 18/38] =?UTF-8?q?update:=20#426:=20`TownMasterRepository#g?= =?UTF-8?q?et=5Fblocking`=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=81=8B=E3=82=89=E9=96=A2=E9=80=A3=E9=96=A2=E6=95=B0=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ChimeiRuijuApiService`は引数で受け取るように変更 --- core/src/repository/chimei_ruiju/town.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs index 4ce1eb22..436575ef 100644 --- a/core/src/repository/chimei_ruiju/town.rs +++ b/core/src/repository/chimei_ruiju/town.rs @@ -45,7 +45,7 @@ mod async_tests { #[cfg(feature = "blocking")] impl TownMasterRepository { pub fn get_blocking( - &self, + api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, city_name: &str, town_name: &str, @@ -56,7 +56,7 @@ impl TownMasterRepository { city_name, town_name ); - self.api_service.get_blocking::(&url) + api_service.get_blocking::(&url) } } @@ -68,10 +68,13 @@ mod blocking_tests { #[test] fn 京都府京都市伏見区魚屋町() { - let repository = TownMasterRepository { - api_service: ChimeiRuijuApiService {}, - }; - let result = repository.get_blocking(&Prefecture::KYOTO, "京都市伏見区", "魚屋町"); + let api_service = ChimeiRuijuApiService {}; + let result = TownMasterRepository::get_blocking( + &api_service, + &Prefecture::KYOTO, + "京都市伏見区", + "魚屋町", + ); assert!(result.is_ok()); let entity = result.unwrap(); assert_eq!(entity.name, "魚屋町"); From bd239f703fbb4fa5a92e018a39bc30c98601ea02 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Mon, 16 Sep 2024 22:55:39 +0900 Subject: [PATCH 19/38] =?UTF-8?q?update:=20#426:=20=E6=A7=8B=E9=80=A0?= =?UTF-8?q?=E4=BD=93`TownMasterRepository`=E3=81=8B=E3=82=89=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=83=BC=E3=83=AB=E3=83=89`api=5Fservice`=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/repository/chimei_ruiju/town.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs index 436575ef..e7bf0151 100644 --- a/core/src/repository/chimei_ruiju/town.rs +++ b/core/src/repository/chimei_ruiju/town.rs @@ -4,9 +4,7 @@ use crate::service::chimei_ruiju::ChimeiRuijuApiService; use jisx0401::Prefecture; #[allow(dead_code)] -pub struct TownMasterRepository { - api_service: ChimeiRuijuApiService, -} +pub struct TownMasterRepository {} impl TownMasterRepository { pub async fn get( From e5ef18fc8d5ea6d91745b5be6d2c10bc52f9cc4a Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 19 Oct 2024 02:01:44 +0900 Subject: [PATCH 20/38] =?UTF-8?q?add:=20#426:=20`interactor`=E3=83=A2?= =?UTF-8?q?=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `parser`と`repository`の間を取り持つモジュール --- core/src/interactor.rs | 1 + core/src/lib.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 core/src/interactor.rs diff --git a/core/src/interactor.rs b/core/src/interactor.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/core/src/interactor.rs @@ -0,0 +1 @@ + diff --git a/core/src/lib.rs b/core/src/lib.rs index bfe75fd8..fafb3d50 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -16,6 +16,7 @@ pub(crate) mod domain; #[deprecated(since = "0.1.6", note = "This module will be deleted in v0.2")] pub mod entity; mod formatter; +mod interactor; pub mod parser; mod repository; mod service; From b774c422a679b2c3d40352f53970a4b80e729036 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 19 Oct 2024 22:47:15 +0900 Subject: [PATCH 21/38] =?UTF-8?q?add:=20#426:=20`ChimeiRuijuInteractor`?= =?UTF-8?q?=E3=82=92=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/interactor.rs | 70 +++++++++++++++++++++++++++++ core/src/repository/chimei_ruiju.rs | 2 +- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 8b137891..58882983 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -1 +1,71 @@ +use crate::domain::chimei_ruiju::entity::{CityMaster, PrefectureMaster, TownMaster}; +use crate::domain::chimei_ruiju::error::ApiError; +use crate::repository::chimei_ruiju::city::CityMasterRepository; +use crate::repository::chimei_ruiju::prefecture::PrefectureMasterRepository; +use crate::repository::chimei_ruiju::town::TownMasterRepository; +use crate::service::chimei_ruiju::ChimeiRuijuApiService; +use jisx0401::Prefecture; +#[allow(dead_code)] +pub(crate) trait ChimeiRuijuInteractor { + /// 都道府県マスタを取得 + async fn get_prefecture_master( + &self, + prefecture_name: &str, + ) -> Result; + /// 市区町村マスタを取得 + async fn get_city_master( + &self, + prefecture_name: &str, + city_name: &str, + ) -> Result; + /// 町名マスタを取得 + async fn get_town_master( + &self, + prefecture_name: &str, + city_name: &str, + town_name: &str, + ) -> Result; +} + +#[allow(dead_code)] +pub(crate) struct ChimeiRuijuInteractorImpl { + api_service: ChimeiRuijuApiService, +} + +impl Default for ChimeiRuijuInteractorImpl { + fn default() -> Self { + Self { + api_service: ChimeiRuijuApiService {}, + } + } +} + +impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { + async fn get_prefecture_master( + &self, + prefecture_name: &str, + ) -> Result { + let prefecture = Prefecture::try_from(prefecture_name).unwrap(); + PrefectureMasterRepository::get(&self.api_service, &prefecture).await + } + + async fn get_city_master( + &self, + prefecture_name: &str, + city_name: &str, + ) -> Result { + let prefecture = Prefecture::try_from(prefecture_name).unwrap(); + CityMasterRepository::get(&self.api_service, &prefecture, city_name).await + } + + async fn get_town_master( + &self, + prefecture_name: &str, + city_name: &str, + town_name: &str, + ) -> Result { + let prefecture = Prefecture::try_from(prefecture_name).unwrap(); + TownMasterRepository::get(&self.api_service, &prefecture, city_name, town_name).await + } +} diff --git a/core/src/repository/chimei_ruiju.rs b/core/src/repository/chimei_ruiju.rs index 5c4bae46..f74ba473 100644 --- a/core/src/repository/chimei_ruiju.rs +++ b/core/src/repository/chimei_ruiju.rs @@ -1,3 +1,3 @@ pub mod city; pub mod prefecture; -mod town; +pub mod town; From 0a1d9dfc7a33d41e9417b4f78f115645311e1354 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sun, 20 Oct 2024 01:05:18 +0900 Subject: [PATCH 22/38] =?UTF-8?q?update:=20#426:=20`ChimeiRuijuInteractor#?= =?UTF-8?q?get=5Fprefecture=5Fmaster`=E3=81=AE=E5=BC=95=E6=95=B0=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `prefecture_name: &str` -> `prefecture: &jisx0401::Prefecture` --- core/src/interactor.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 58882983..2bc43687 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -11,7 +11,7 @@ pub(crate) trait ChimeiRuijuInteractor { /// 都道府県マスタを取得 async fn get_prefecture_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, ) -> Result; /// 市区町村マスタを取得 async fn get_city_master( @@ -44,10 +44,9 @@ impl Default for ChimeiRuijuInteractorImpl { impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { async fn get_prefecture_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, ) -> Result { - let prefecture = Prefecture::try_from(prefecture_name).unwrap(); - PrefectureMasterRepository::get(&self.api_service, &prefecture).await + PrefectureMasterRepository::get(&self.api_service, prefecture).await } async fn get_city_master( From 47f3a95c198b3dc1d727bed74c8a55c045686166 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sun, 20 Oct 2024 01:05:38 +0900 Subject: [PATCH 23/38] =?UTF-8?q?update:=20#426:=20`ChimeiRuijuInteractor#?= =?UTF-8?q?get=5Fcity=5Fmaster`=E3=81=AE=E5=BC=95=E6=95=B0=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `prefecture_name: &str` -> `prefecture: &jisx0401::Prefecture` --- core/src/interactor.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 2bc43687..7a3e08d0 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -16,7 +16,7 @@ pub(crate) trait ChimeiRuijuInteractor { /// 市区町村マスタを取得 async fn get_city_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, city_name: &str, ) -> Result; /// 町名マスタを取得 @@ -51,11 +51,10 @@ impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { async fn get_city_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, city_name: &str, ) -> Result { - let prefecture = Prefecture::try_from(prefecture_name).unwrap(); - CityMasterRepository::get(&self.api_service, &prefecture, city_name).await + CityMasterRepository::get(&self.api_service, prefecture, city_name).await } async fn get_town_master( From ce1f0ed8b0e4a229bb12704b1ba248b92591baac Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sun, 20 Oct 2024 01:05:58 +0900 Subject: [PATCH 24/38] =?UTF-8?q?update:=20#426:=20`ChimeiRuijuInteractor#?= =?UTF-8?q?get=5Ftown=5Fmaster`=E3=81=AE=E5=BC=95=E6=95=B0=E3=82=92?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `prefecture_name: &str` -> `prefecture: &jisx0401::Prefecture` --- core/src/interactor.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 7a3e08d0..87de62b9 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -22,7 +22,7 @@ pub(crate) trait ChimeiRuijuInteractor { /// 町名マスタを取得 async fn get_town_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, city_name: &str, town_name: &str, ) -> Result; @@ -59,11 +59,10 @@ impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { async fn get_town_master( &self, - prefecture_name: &str, + prefecture: &Prefecture, city_name: &str, town_name: &str, ) -> Result { - let prefecture = Prefecture::try_from(prefecture_name).unwrap(); - TownMasterRepository::get(&self.api_service, &prefecture, city_name, town_name).await + TownMasterRepository::get(&self.api_service, prefecture, city_name, town_name).await } } From 7a6965c8e4c6239aa1184f6096c5767d6c818dea Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 22:33:38 +0900 Subject: [PATCH 25/38] =?UTF-8?q?add:=20#426:=20`parse=5Fwith=5Fchimeiruij?= =?UTF-8?q?u()`=E3=82=92=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/experimental.rs | 1 + .../experimental/parse_with_chimeiruiju.rs | 77 +++++++++++++++++++ core/src/interactor.rs | 2 - 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 core/src/experimental/parse_with_chimeiruiju.rs diff --git a/core/src/experimental.rs b/core/src/experimental.rs index 18947fa5..29dd3eec 100644 --- a/core/src/experimental.rs +++ b/core/src/experimental.rs @@ -6,5 +6,6 @@ //! //! If you are eager to use this module, please enable `experimental` feature flag. +mod parse_with_chimeiruiju; mod parse_with_geolonia; pub mod parser; diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs new file mode 100644 index 00000000..02baedc1 --- /dev/null +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -0,0 +1,77 @@ +use crate::domain::common::token::Token; +use crate::experimental::parser::Parser; +use crate::interactor::{ChimeiRuijuInteractor, ChimeiRuijuInteractorImpl}; +use crate::tokenizer::Tokenizer; + +impl Parser { + pub(crate) async fn parse_with_chimeiruiju(&self, address: &str) -> Vec { + let interactor = ChimeiRuijuInteractorImpl::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 interactor.get_prefecture_master(&prefecture).await { + Ok(result) => result, + Err(error) => { + if self.options.verbose { + log::error!("{}", error) + } + 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 interactor.get_city_master(&prefecture, &city_name).await { + Ok(result) => result, + Err(error) => { + if self.options.verbose { + log::error!("{}", error) + } + return tokenizer.finish().tokens; + } + }; + let (_, tokenizer) = match tokenizer.read_town(city_master.towns) { + Ok(found) => found, + Err(not_found) => { + if self.options.verbose { + log::error!("町名の検出に失敗しました") + } + return not_found.tokens; + } + }; + + tokenizer.finish().tokens + } +} diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 87de62b9..0b5f4d52 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -6,7 +6,6 @@ use crate::repository::chimei_ruiju::town::TownMasterRepository; use crate::service::chimei_ruiju::ChimeiRuijuApiService; use jisx0401::Prefecture; -#[allow(dead_code)] pub(crate) trait ChimeiRuijuInteractor { /// 都道府県マスタを取得 async fn get_prefecture_master( @@ -28,7 +27,6 @@ pub(crate) trait ChimeiRuijuInteractor { ) -> Result; } -#[allow(dead_code)] pub(crate) struct ChimeiRuijuInteractorImpl { api_service: ChimeiRuijuApiService, } From 17e1ba0ed4baed82ec437e80dbf5a3832b5713fc Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 22:38:20 +0900 Subject: [PATCH 26/38] =?UTF-8?q?add:=20#426:=20enum`DataSource`=E3=81=AB`?= =?UTF-8?q?ChimeiRuiju`=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/experimental/parser.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/experimental/parser.rs b/core/src/experimental/parser.rs index 756b39d0..e5d32316 100644 --- a/core/src/experimental/parser.rs +++ b/core/src/experimental/parser.rs @@ -6,6 +6,9 @@ use serde::Serialize; /// パーサーで使用するデータソースを指定します。 #[derive(Debug)] pub enum DataSource { + /// ChimeiRuiju 住所データ + /// + ChimeiRuiju, /// Geolonia 住所データ /// Geolonia, @@ -90,6 +93,7 @@ impl Parser { /// ``` pub async fn parse(&self, address: &str) -> ParsedAddress { let tokens = match self.options.data_source { + DataSource::ChimeiRuiju => self.parse_with_chimeiruiju(address).await, DataSource::Geolonia => self.parse_with_geolonia(address).await, }; ParsedAddress::from(tokens) From 167269510a463339cf1f473eeaa2576605eb9e8e Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 22:41:25 +0900 Subject: [PATCH 27/38] =?UTF-8?q?add:=20#426:=20`parse=5Fwith=5Fchimeiruij?= =?UTF-8?q?u()`=E3=81=AB=E5=AF=BE=E3=81=97=E3=81=A6=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../experimental/parse_with_chimeiruiju.rs | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index 02baedc1..92d811ca 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -75,3 +75,111 @@ impl Parser { 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::ChimeiRuiju, + 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::ChimeiRuiju, + 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::ChimeiRuiju, + 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::ChimeiRuiju, + 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()) + ] + ) + } +} From 5bd9f852a3f82e29bef70da41cac012073be521a Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 22:56:36 +0900 Subject: [PATCH 28/38] =?UTF-8?q?fix:=20#426:=20`DataSource`=E3=81=AE`Defa?= =?UTF-8?q?ult`=E3=83=88=E3=83=AC=E3=82=A4=E3=83=88=E3=81=AE=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E3=82=92=E6=89=8B=E6=9B=B8=E3=81=8D=E3=81=A7=E8=A1=8C?= =?UTF-8?q?=E3=81=AA=E3=81=86=E3=81=AE=E3=82=92=E3=82=84=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clippyの警告対応 https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls --- core/src/experimental/parser.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/core/src/experimental/parser.rs b/core/src/experimental/parser.rs index e5d32316..8c3e8c3d 100644 --- a/core/src/experimental/parser.rs +++ b/core/src/experimental/parser.rs @@ -4,22 +4,17 @@ use serde::Serialize; /// Data source for Parser /// /// パーサーで使用するデータソースを指定します。 -#[derive(Debug)] +#[derive(Debug, Default)] pub enum DataSource { /// ChimeiRuiju 住所データ /// ChimeiRuiju, /// Geolonia 住所データ /// + #[default] Geolonia, } -impl Default for DataSource { - fn default() -> Self { - DataSource::Geolonia - } -} - /// Options for Parser /// /// パーサーのオプションを指定します。 From 2348190c48cc03e4e0d89c4912b7ea5b476d1b89 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 23:40:46 +0900 Subject: [PATCH 29/38] =?UTF-8?q?update:=20#426:=20`core/src/interactor.rs?= =?UTF-8?q?`=E3=81=AE=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92`core/src/interac?= =?UTF-8?q?tor/chimei=5Fruiju.rs`=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../experimental/parse_with_chimeiruiju.rs | 2 +- core/src/interactor.rs | 67 +------------------ core/src/interactor/chimei_ruiju.rs | 66 ++++++++++++++++++ 3 files changed, 68 insertions(+), 67 deletions(-) create mode 100644 core/src/interactor/chimei_ruiju.rs diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index 92d811ca..73c8f4de 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -1,6 +1,6 @@ use crate::domain::common::token::Token; use crate::experimental::parser::Parser; -use crate::interactor::{ChimeiRuijuInteractor, ChimeiRuijuInteractorImpl}; +use crate::interactor::chimei_ruiju::{ChimeiRuijuInteractor, ChimeiRuijuInteractorImpl}; use crate::tokenizer::Tokenizer; impl Parser { diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 0b5f4d52..23189d83 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -1,66 +1 @@ -use crate::domain::chimei_ruiju::entity::{CityMaster, PrefectureMaster, TownMaster}; -use crate::domain::chimei_ruiju::error::ApiError; -use crate::repository::chimei_ruiju::city::CityMasterRepository; -use crate::repository::chimei_ruiju::prefecture::PrefectureMasterRepository; -use crate::repository::chimei_ruiju::town::TownMasterRepository; -use crate::service::chimei_ruiju::ChimeiRuijuApiService; -use jisx0401::Prefecture; - -pub(crate) trait ChimeiRuijuInteractor { - /// 都道府県マスタを取得 - async fn get_prefecture_master( - &self, - prefecture: &Prefecture, - ) -> Result; - /// 市区町村マスタを取得 - async fn get_city_master( - &self, - prefecture: &Prefecture, - city_name: &str, - ) -> Result; - /// 町名マスタを取得 - async fn get_town_master( - &self, - prefecture: &Prefecture, - city_name: &str, - town_name: &str, - ) -> Result; -} - -pub(crate) struct ChimeiRuijuInteractorImpl { - api_service: ChimeiRuijuApiService, -} - -impl Default for ChimeiRuijuInteractorImpl { - fn default() -> Self { - Self { - api_service: ChimeiRuijuApiService {}, - } - } -} - -impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { - async fn get_prefecture_master( - &self, - prefecture: &Prefecture, - ) -> Result { - PrefectureMasterRepository::get(&self.api_service, prefecture).await - } - - async fn get_city_master( - &self, - prefecture: &Prefecture, - city_name: &str, - ) -> Result { - CityMasterRepository::get(&self.api_service, prefecture, city_name).await - } - - async fn get_town_master( - &self, - prefecture: &Prefecture, - city_name: &str, - town_name: &str, - ) -> Result { - TownMasterRepository::get(&self.api_service, prefecture, city_name, town_name).await - } -} +pub mod chimei_ruiju; diff --git a/core/src/interactor/chimei_ruiju.rs b/core/src/interactor/chimei_ruiju.rs new file mode 100644 index 00000000..0b5f4d52 --- /dev/null +++ b/core/src/interactor/chimei_ruiju.rs @@ -0,0 +1,66 @@ +use crate::domain::chimei_ruiju::entity::{CityMaster, PrefectureMaster, TownMaster}; +use crate::domain::chimei_ruiju::error::ApiError; +use crate::repository::chimei_ruiju::city::CityMasterRepository; +use crate::repository::chimei_ruiju::prefecture::PrefectureMasterRepository; +use crate::repository::chimei_ruiju::town::TownMasterRepository; +use crate::service::chimei_ruiju::ChimeiRuijuApiService; +use jisx0401::Prefecture; + +pub(crate) trait ChimeiRuijuInteractor { + /// 都道府県マスタを取得 + async fn get_prefecture_master( + &self, + prefecture: &Prefecture, + ) -> Result; + /// 市区町村マスタを取得 + async fn get_city_master( + &self, + prefecture: &Prefecture, + city_name: &str, + ) -> Result; + /// 町名マスタを取得 + async fn get_town_master( + &self, + prefecture: &Prefecture, + city_name: &str, + town_name: &str, + ) -> Result; +} + +pub(crate) struct ChimeiRuijuInteractorImpl { + api_service: ChimeiRuijuApiService, +} + +impl Default for ChimeiRuijuInteractorImpl { + fn default() -> Self { + Self { + api_service: ChimeiRuijuApiService {}, + } + } +} + +impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { + async fn get_prefecture_master( + &self, + prefecture: &Prefecture, + ) -> Result { + PrefectureMasterRepository::get(&self.api_service, prefecture).await + } + + async fn get_city_master( + &self, + prefecture: &Prefecture, + city_name: &str, + ) -> Result { + CityMasterRepository::get(&self.api_service, prefecture, city_name).await + } + + async fn get_town_master( + &self, + prefecture: &Prefecture, + city_name: &str, + town_name: &str, + ) -> Result { + TownMasterRepository::get(&self.api_service, prefecture, city_name, town_name).await + } +} From 8edf463b96c73cd6c57d53f2cf10061258ad0831 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 23:27:22 +0900 Subject: [PATCH 30/38] =?UTF-8?q?update:=20#426:=20=E7=8F=BE=E6=99=82?= =?UTF-8?q?=E7=82=B9=E3=81=A7=E4=BD=BF=E7=94=A8=E3=81=95=E3=82=8C=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=84=E6=A7=8B=E9=80=A0=E4=BD=93=E3=80=81?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB`#[allow(dead=5Fco?= =?UTF-8?q?de)]`=E3=82=92=E4=BB=98=E4=B8=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clippyの警告を抑制したいため。現時点では使用されていないが将来的には使用される予定。 --- core/src/domain/chimei_ruiju/entity.rs | 2 ++ core/src/interactor/chimei_ruiju.rs | 2 ++ core/src/repository/chimei_ruiju/city.rs | 1 + core/src/repository/chimei_ruiju/prefecture.rs | 1 + core/src/repository/chimei_ruiju/town.rs | 2 ++ 5 files changed, 8 insertions(+) diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs index 1d793d27..cbe45bcd 100644 --- a/core/src/domain/chimei_ruiju/entity.rs +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -30,6 +30,7 @@ pub struct TownMaster { coordinate: Coordinate, } +#[allow(dead_code)] #[derive(Deserialize, Debug)] pub struct Block { /// 小字・通称名 @@ -42,6 +43,7 @@ pub struct Block { coordinate: Coordinate, } +#[allow(dead_code)] #[derive(Deserialize, Debug)] pub struct Coordinate { /// 緯度 diff --git a/core/src/interactor/chimei_ruiju.rs b/core/src/interactor/chimei_ruiju.rs index 0b5f4d52..9488e809 100644 --- a/core/src/interactor/chimei_ruiju.rs +++ b/core/src/interactor/chimei_ruiju.rs @@ -19,6 +19,7 @@ pub(crate) trait ChimeiRuijuInteractor { city_name: &str, ) -> Result; /// 町名マスタを取得 + #[allow(dead_code)] async fn get_town_master( &self, prefecture: &Prefecture, @@ -55,6 +56,7 @@ impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { CityMasterRepository::get(&self.api_service, prefecture, city_name).await } + #[allow(dead_code)] async fn get_town_master( &self, prefecture: &Prefecture, diff --git a/core/src/repository/chimei_ruiju/city.rs b/core/src/repository/chimei_ruiju/city.rs index a788390c..c0fcf164 100644 --- a/core/src/repository/chimei_ruiju/city.rs +++ b/core/src/repository/chimei_ruiju/city.rs @@ -51,6 +51,7 @@ mod async_tests { #[cfg(feature = "blocking")] impl CityMasterRepository { + #[allow(dead_code)] pub fn get_blocking( api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, diff --git a/core/src/repository/chimei_ruiju/prefecture.rs b/core/src/repository/chimei_ruiju/prefecture.rs index 48269e20..4b563c91 100644 --- a/core/src/repository/chimei_ruiju/prefecture.rs +++ b/core/src/repository/chimei_ruiju/prefecture.rs @@ -132,6 +132,7 @@ mod async_tests { #[cfg(feature = "blocking")] impl PrefectureMasterRepository { + #[allow(dead_code)] pub fn get_blocking( api_service: &ChimeiRuijuApiService, prefecture: Prefecture, diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs index e7bf0151..2e75e27b 100644 --- a/core/src/repository/chimei_ruiju/town.rs +++ b/core/src/repository/chimei_ruiju/town.rs @@ -7,6 +7,7 @@ use jisx0401::Prefecture; pub struct TownMasterRepository {} impl TownMasterRepository { + #[allow(dead_code)] pub async fn get( api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, @@ -42,6 +43,7 @@ mod async_tests { #[cfg(feature = "blocking")] impl TownMasterRepository { + #[allow(dead_code)] pub fn get_blocking( api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, From 2b8770b5a78b343470295b73d2340424a22562b2 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Thu, 31 Oct 2024 23:37:24 +0900 Subject: [PATCH 31/38] =?UTF-8?q?update:=20#426:=20ChimeiRuiju=E7=94=A8?= =?UTF-8?q?=E3=81=AE=E3=83=A2=E3=82=B8=E3=83=A5=E3=83=BC=E3=83=AB=E3=81=AF?= =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=81=E3=83=A3=E3=83=95=E3=83=A9?= =?UTF-8?q?=E3=82=B0`experimental`=E3=82=92=E6=9C=89=E5=8A=B9=E5=8C=96?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=81=A8=E3=81=8D=E3=81=AE=E3=81=BF=E3=83=93?= =?UTF-8?q?=E3=83=AB=E3=83=89=E3=81=95=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E8=A8=AD=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 現時点では`experimental::Parser`以外からは使用されていないため --- core/src/domain.rs | 1 + core/src/interactor.rs | 1 + core/src/repository.rs | 1 + core/src/service.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/core/src/domain.rs b/core/src/domain.rs index dff17fb5..d1184822 100644 --- a/core/src/domain.rs +++ b/core/src/domain.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "experimental")] pub mod chimei_ruiju; pub mod common; pub mod geolonia; diff --git a/core/src/interactor.rs b/core/src/interactor.rs index 23189d83..d7483914 100644 --- a/core/src/interactor.rs +++ b/core/src/interactor.rs @@ -1 +1,2 @@ +#[cfg(feature = "experimental")] pub mod chimei_ruiju; diff --git a/core/src/repository.rs b/core/src/repository.rs index 9df7829d..d947d766 100644 --- a/core/src/repository.rs +++ b/core/src/repository.rs @@ -1,2 +1,3 @@ +#[cfg(feature = "experimental")] pub mod chimei_ruiju; pub mod geolonia; diff --git a/core/src/service.rs b/core/src/service.rs index 9df7829d..d947d766 100644 --- a/core/src/service.rs +++ b/core/src/service.rs @@ -1,2 +1,3 @@ +#[cfg(feature = "experimental")] pub mod chimei_ruiju; pub mod geolonia; From 4b514155d09f75647cabd0b450e9f9f67f64fbfc Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Fri, 1 Nov 2024 01:10:19 +0900 Subject: [PATCH 32/38] =?UTF-8?q?update:=20#426:=20=E3=83=87=E3=83=A2?= =?UTF-8?q?=E3=83=9A=E3=83=BC=E3=82=B8`nightly.html`=E3=81=AB=E4=BD=8F?= =?UTF-8?q?=E6=89=80=E3=83=87=E3=83=BC=E3=82=BF=E3=81=AE=E9=81=B8=E6=8A=9E?= =?UTF-8?q?=E3=82=92=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81=E3=81=AE=E3=83=A9?= =?UTF-8?q?=E3=82=B8=E3=82=AA=E3=83=9C=E3=82=BF=E3=83=B3=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/nightly.html | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/public/nightly.html b/public/nightly.html index 68a08d6a..24106b6a 100644 --- a/public/nightly.html +++ b/public/nightly.html @@ -14,11 +14,23 @@

YuukiToriyama/japanese-address-parser

オプションを指定してください

- - -
- - +
+
+ パースに使用する住所データ +
+ + + + +
+
+
+ + +
+ + +

住所を入力してください

@@ -65,7 +77,7 @@

処理結果

const input = inputTextArea.value alert("input: " + input) parse_experimental(input, { - dataSource: "geolonia", + dataSource: document.getElementById("radioGroup").dataSource.value, correctIncompleteCityNames: document.getElementById("auto_completion").checked, verbose: document.getElementById("enable_log_output").checked, }).then(result => { From 79aaa8526e728f03465b78354f2f82a11ff5042f Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Fri, 1 Nov 2024 01:11:52 +0900 Subject: [PATCH 33/38] =?UTF-8?q?update:=20#426:=20wasm=E3=83=A2=E3=82=B8?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=83=AB=E3=81=AB=E3=81=8A=E3=81=84=E3=81=A6?= =?UTF-8?q?=E3=82=82`DataSource::ChimeiRuiju`=E3=82=92=E9=81=B8=E6=8A=9E?= =?UTF-8?q?=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=97?= =?UTF-8?q?=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wasm/src/nightly.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wasm/src/nightly.rs b/wasm/src/nightly.rs index c686beb4..bbe07dea 100644 --- a/wasm/src/nightly.rs +++ b/wasm/src/nightly.rs @@ -11,7 +11,7 @@ export function parse_experimental( ): Promise; export interface ParseOptions { - dataSource: "geolonia"; + dataSource: "chimeiruiju" | "geolonia"; correctIncompleteCityNames: boolean | null; verbose: boolean | null; } @@ -56,10 +56,10 @@ pub async fn parse_experimental(address: &str, options: JsValue) -> JsValue { ParserOptions::default() } Ok(options) => ParserOptions { - data_source: if options.data_source == "geolonia" { - DataSource::Geolonia - } else { - DataSource::default() + data_source: match options.data_source.as_str() { + "chimeiruiju" => DataSource::ChimeiRuiju, + "geolonia" => DataSource::Geolonia, + _ => DataSource::default(), }, correct_incomplete_city_names: match options.correct_incomplete_city_names { Some(boolean) => boolean, From 1739d3ecec6a03260502106363880200bb764319 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 2 Nov 2024 00:58:20 +0900 Subject: [PATCH 34/38] =?UTF-8?q?fix:=20#426:=20`Parser#parse=5Fwith=5Fchi?= =?UTF-8?q?meiruiju`=E3=81=AB=E5=AF=BE=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ChimeiRuijuではなくGeoloniaのデータを使うテストになっていたため --- core/src/experimental/parse_with_chimeiruiju.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index 73c8f4de..90955cfc 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -91,7 +91,7 @@ mod tests { }, }; let result = parser - .parse_with_geolonia("奈川県横浜市磯子区洋光台3-10-3") + .parse_with_chimeiruiju("奈川県横浜市磯子区洋光台3-10-3") .await; assert_eq!( result, @@ -109,7 +109,7 @@ mod tests { }, }; let result = parser - .parse_with_geolonia("神奈川県横浜県磯子市洋光台3-10-3") + .parse_with_chimeiruiju("神奈川県横浜県磯子市洋光台3-10-3") .await; assert_eq!( result, @@ -133,7 +133,7 @@ mod tests { }, }; let result = parser - .parse_with_geolonia("神奈川県横浜市磯子区陽光台3-10-3") + .parse_with_chimeiruiju("神奈川県横浜市磯子区陽光台3-10-3") .await; assert_eq!( result, @@ -161,7 +161,7 @@ mod tests { }, }; let result = parser - .parse_with_geolonia("神奈川県横浜市磯子区洋光台3-10-3") + .parse_with_chimeiruiju("神奈川県横浜市磯子区洋光台3-10-3") .await; assert_eq!( result, From 5028539429712717dae2fca0d73d3c683d208a83 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 2 Nov 2024 00:46:06 +0900 Subject: [PATCH 35/38] =?UTF-8?q?update:=20#426:=20=E9=83=BD=E9=81=93?= =?UTF-8?q?=E5=BA=9C=E7=9C=8C=E3=83=9E=E3=82=B9=E3=82=BF=E3=83=BB=E5=B8=82?= =?UTF-8?q?=E5=8C=BA=E7=94=BA=E6=9D=91=E3=83=9E=E3=82=B9=E3=82=BF=E3=81=AE?= =?UTF-8?q?=E5=8F=96=E5=BE=97=E6=88=90=E5=8A=9F=E3=81=97=E3=81=9F=E9=9A=9B?= =?UTF-8?q?=E3=81=AB=E3=80=81=E3=81=9D=E3=82=8C=E3=81=9E=E3=82=8C=E3=81=AE?= =?UTF-8?q?=E4=BB=A3=E8=A1=A8=E7=82=B9=E3=81=AE=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=81=8C=E5=8F=96=E3=82=8C=E3=82=8B=E3=81=AE=E3=81=A7=E3=83=AD?= =?UTF-8?q?=E3=83=BC=E3=82=AB=E3=83=AB=E5=A4=89=E6=95=B0=E3=81=AB=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/domain/chimei_ruiju/entity.rs | 12 ++++++++++- .../experimental/parse_with_chimeiruiju.rs | 20 +++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs index cbe45bcd..27c4d059 100644 --- a/core/src/domain/chimei_ruiju/entity.rs +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -1,3 +1,4 @@ +use crate::domain::common::latlng::LatLng; use serde::Deserialize; #[derive(Deserialize, Debug)] @@ -17,7 +18,7 @@ pub struct CityMaster { /// 町名リスト pub(crate) towns: Vec, /// 緯度経度 - coordinate: Coordinate, + pub(crate) coordinate: Coordinate, } #[derive(Deserialize, Debug)] @@ -51,3 +52,12 @@ pub struct Coordinate { /// 経度 pub(crate) longitude: f64, } + +impl Coordinate { + pub(crate) fn to_lat_lng(&self) -> LatLng { + LatLng { + latitude: self.latitude, + longitude: self.longitude, + } + } +} diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index 90955cfc..e3605bdd 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -1,12 +1,15 @@ +use crate::domain::common::latlng::LatLng; use crate::domain::common::token::Token; use crate::experimental::parser::Parser; use crate::interactor::chimei_ruiju::{ChimeiRuijuInteractor, ChimeiRuijuInteractorImpl}; use crate::tokenizer::Tokenizer; +use std::option::Option; impl Parser { pub(crate) async fn parse_with_chimeiruiju(&self, address: &str) -> Vec { let interactor = ChimeiRuijuInteractorImpl::default(); let tokenizer = Tokenizer::new(address); + let mut lat_lng: Option = None; // 都道府県名の検出 let (prefecture, tokenizer) = match tokenizer.read_prefecture() { @@ -19,9 +22,12 @@ impl Parser { } }; - // 市区町村名の検出 + // 都道府県マスタの取得 let prefecture_master = match interactor.get_prefecture_master(&prefecture).await { - Ok(result) => result, + Ok(result) => { + lat_lng.replace(result.coordinate.to_lat_lng()); + result + } Err(error) => { if self.options.verbose { log::error!("{}", error) @@ -29,6 +35,7 @@ impl Parser { return tokenizer.finish().tokens; } }; + // 市区町村名の検出 let (city_name, tokenizer) = match tokenizer.read_city(&prefecture_master.cities) { Ok(found) => found, Err(not_found) => { @@ -52,9 +59,12 @@ impl Parser { } }; - // 町名の検出 + // 市区町村マスタの取得 let city_master = match interactor.get_city_master(&prefecture, &city_name).await { - Ok(result) => result, + Ok(result) => { + lat_lng.replace(result.coordinate.to_lat_lng()); + result + } Err(error) => { if self.options.verbose { log::error!("{}", error) @@ -62,6 +72,7 @@ impl Parser { return tokenizer.finish().tokens; } }; + // 町名の検出 let (_, tokenizer) = match tokenizer.read_town(city_master.towns) { Ok(found) => found, Err(not_found) => { @@ -72,6 +83,7 @@ impl Parser { } }; + log::info!("{:?}", lat_lng); tokenizer.finish().tokens } } From 68057357008656673fafc679602660dabcd12078 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 2 Nov 2024 00:50:05 +0900 Subject: [PATCH 36/38] =?UTF-8?q?update:=20#426:=20=E7=94=BA=E5=90=8D?= =?UTF-8?q?=E3=81=BE=E3=81=A7=E6=A4=9C=E5=87=BA=E3=81=A7=E3=81=8D=E3=81=9F?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=AF=E6=9B=B4=E3=81=AB=E7=94=BA=E6=9D=91?= =?UTF-8?q?=E3=83=9E=E3=82=B9=E3=82=BF=E3=81=AE=E5=8F=96=E5=BE=97=E3=82=92?= =?UTF-8?q?=E8=A9=A6=E3=81=BF=E3=80=81=E5=8F=96=E5=BE=97=E6=88=90=E5=8A=9F?= =?UTF-8?q?=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AF=E3=81=9D=E3=81=AE?= =?UTF-8?q?=E4=BB=A3=E8=A1=A8=E7=82=B9=E3=81=AE=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=82=92=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E3=81=AB=E4=BF=9D=E5=AD=98=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/domain/chimei_ruiju/entity.rs | 2 +- core/src/experimental/parse_with_chimeiruiju.rs | 10 +++++++++- core/src/interactor/chimei_ruiju.rs | 1 - core/src/repository/chimei_ruiju/town.rs | 2 -- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/core/src/domain/chimei_ruiju/entity.rs b/core/src/domain/chimei_ruiju/entity.rs index 27c4d059..4572474b 100644 --- a/core/src/domain/chimei_ruiju/entity.rs +++ b/core/src/domain/chimei_ruiju/entity.rs @@ -28,7 +28,7 @@ pub struct TownMaster { /// 街区リスト blocks: Vec, /// 緯度経度 - coordinate: Coordinate, + pub(crate) coordinate: Coordinate, } #[allow(dead_code)] diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index e3605bdd..c01bf291 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -73,7 +73,7 @@ impl Parser { } }; // 町名の検出 - let (_, tokenizer) = match tokenizer.read_town(city_master.towns) { + let (town_name, tokenizer) = match tokenizer.read_town(city_master.towns) { Ok(found) => found, Err(not_found) => { if self.options.verbose { @@ -83,6 +83,14 @@ impl Parser { } }; + // 町村マスタの取得 + if let Ok(town_master) = interactor + .get_town_master(&prefecture, &city_name, &town_name) + .await + { + lat_lng.replace(town_master.coordinate.to_lat_lng()); + }; + log::info!("{:?}", lat_lng); tokenizer.finish().tokens } diff --git a/core/src/interactor/chimei_ruiju.rs b/core/src/interactor/chimei_ruiju.rs index 9488e809..538683ef 100644 --- a/core/src/interactor/chimei_ruiju.rs +++ b/core/src/interactor/chimei_ruiju.rs @@ -56,7 +56,6 @@ impl ChimeiRuijuInteractor for ChimeiRuijuInteractorImpl { CityMasterRepository::get(&self.api_service, prefecture, city_name).await } - #[allow(dead_code)] async fn get_town_master( &self, prefecture: &Prefecture, diff --git a/core/src/repository/chimei_ruiju/town.rs b/core/src/repository/chimei_ruiju/town.rs index 2e75e27b..a27d21da 100644 --- a/core/src/repository/chimei_ruiju/town.rs +++ b/core/src/repository/chimei_ruiju/town.rs @@ -3,11 +3,9 @@ use crate::domain::chimei_ruiju::error::ApiError; use crate::service::chimei_ruiju::ChimeiRuijuApiService; use jisx0401::Prefecture; -#[allow(dead_code)] pub struct TownMasterRepository {} impl TownMasterRepository { - #[allow(dead_code)] pub async fn get( api_service: &ChimeiRuijuApiService, prefecture: &Prefecture, From 5dd37b1fc022e6abbce7d9b9a63efb16088a2ef3 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 2 Nov 2024 01:13:00 +0900 Subject: [PATCH 37/38] =?UTF-8?q?add:=20#426:=20`(Vec,=20Option)`=E3=81=8B=E3=82=89`ParseAddress`=E3=81=AB=E5=A4=89?= =?UTF-8?q?=E6=8F=9B=E3=81=99=E3=82=8B=E3=81=9F=E3=82=81=E3=81=AE=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/experimental/parser.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/core/src/experimental/parser.rs b/core/src/experimental/parser.rs index 8c3e8c3d..a5a14bf8 100644 --- a/core/src/experimental/parser.rs +++ b/core/src/experimental/parser.rs @@ -1,3 +1,4 @@ +use crate::domain::common::latlng::LatLng; use crate::domain::common::token::Token; use serde::Serialize; @@ -184,6 +185,17 @@ impl From> for ParsedAddress { } } +impl From<(Vec, Option)> for ParsedAddress { + fn from((tokens, lat_lng): (Vec, Option)) -> Self { + let mut parsed_address = ParsedAddress::from(tokens); + if let Some(lat_lng) = lat_lng { + parsed_address.metadata.longitude = Some(lat_lng.longitude); + parsed_address.metadata.latitude = Some(lat_lng.latitude); + } + parsed_address + } +} + #[cfg(test)] mod tests { use crate::domain::common::latlng::LatLng; From 5522921c5305fa0c1e7a870645db67c70c506441 Mon Sep 17 00:00:00 2001 From: Yuuki Toriyama Date: Sat, 2 Nov 2024 01:14:42 +0900 Subject: [PATCH 38/38] =?UTF-8?q?update:=20#426:=20`parse=5Fwith=5Fchimeir?= =?UTF-8?q?uiju()`=E3=81=AE=E8=BF=94=E3=82=8A=E5=80=A4=E3=81=AE=E5=9E=8B?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Vec`と共に緯度経度情報`Option`を返すようにした --- .../experimental/parse_with_chimeiruiju.rs | 36 ++++++++++--------- core/src/experimental/parser.rs | 11 +++--- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/core/src/experimental/parse_with_chimeiruiju.rs b/core/src/experimental/parse_with_chimeiruiju.rs index c01bf291..df55a85e 100644 --- a/core/src/experimental/parse_with_chimeiruiju.rs +++ b/core/src/experimental/parse_with_chimeiruiju.rs @@ -6,7 +6,10 @@ use crate::tokenizer::Tokenizer; use std::option::Option; impl Parser { - pub(crate) async fn parse_with_chimeiruiju(&self, address: &str) -> Vec { + pub(crate) async fn parse_with_chimeiruiju( + &self, + address: &str, + ) -> (Vec, Option) { let interactor = ChimeiRuijuInteractorImpl::default(); let tokenizer = Tokenizer::new(address); let mut lat_lng: Option = None; @@ -18,7 +21,7 @@ impl Parser { if self.options.verbose { log::error!("都道府県名の検出に失敗しました") } - return not_found.tokens; + return (not_found.tokens, lat_lng); } }; @@ -32,7 +35,7 @@ impl Parser { if self.options.verbose { log::error!("{}", error) } - return tokenizer.finish().tokens; + return (tokenizer.finish().tokens, lat_lng); } }; // 市区町村名の検出 @@ -47,14 +50,14 @@ impl Parser { if self.options.verbose { log::error!("市区町村名の検出に失敗しました") } - return not_found.tokens; + return (not_found.tokens, lat_lng); } } } else { if self.options.verbose { log::error!("市区町村名の検出に失敗しました") } - return not_found.finish().tokens; + return (not_found.finish().tokens, lat_lng); } } }; @@ -69,7 +72,7 @@ impl Parser { if self.options.verbose { log::error!("{}", error) } - return tokenizer.finish().tokens; + return (tokenizer.finish().tokens, lat_lng); } }; // 町名の検出 @@ -79,7 +82,7 @@ impl Parser { if self.options.verbose { log::error!("町名の検出に失敗しました") } - return not_found.tokens; + return (not_found.tokens, lat_lng); } }; @@ -91,8 +94,7 @@ impl Parser { lat_lng.replace(town_master.coordinate.to_lat_lng()); }; - log::info!("{:?}", lat_lng); - tokenizer.finish().tokens + (tokenizer.finish().tokens, lat_lng) } } @@ -110,11 +112,11 @@ mod tests { verbose: false, }, }; - let result = parser + let (tokens, _) = parser .parse_with_chimeiruiju("奈川県横浜市磯子区洋光台3-10-3") .await; assert_eq!( - result, + tokens, vec![Token::Rest("奈川県横浜市磯子区洋光台3-10-3".to_string())] ) } @@ -128,11 +130,11 @@ mod tests { verbose: false, }, }; - let result = parser + let (tokens, _) = parser .parse_with_chimeiruiju("神奈川県横浜県磯子市洋光台3-10-3") .await; assert_eq!( - result, + tokens, vec![ Token::Prefecture(Prefecture { prefecture_name: "神奈川県".to_string(), @@ -152,11 +154,11 @@ mod tests { verbose: false, }, }; - let result = parser + let (tokens, _) = parser .parse_with_chimeiruiju("神奈川県横浜市磯子区陽光台3-10-3") .await; assert_eq!( - result, + tokens, vec![ Token::Prefecture(Prefecture { prefecture_name: "神奈川県".to_string(), @@ -180,11 +182,11 @@ mod tests { verbose: false, }, }; - let result = parser + let (tokens, _) = parser .parse_with_chimeiruiju("神奈川県横浜市磯子区洋光台3-10-3") .await; assert_eq!( - result, + tokens, vec![ Token::Prefecture(Prefecture { prefecture_name: "神奈川県".to_string(), diff --git a/core/src/experimental/parser.rs b/core/src/experimental/parser.rs index a5a14bf8..105192fe 100644 --- a/core/src/experimental/parser.rs +++ b/core/src/experimental/parser.rs @@ -88,11 +88,12 @@ impl Parser { /// } /// ``` pub async fn parse(&self, address: &str) -> ParsedAddress { - let tokens = match self.options.data_source { - DataSource::ChimeiRuiju => self.parse_with_chimeiruiju(address).await, - DataSource::Geolonia => self.parse_with_geolonia(address).await, - }; - ParsedAddress::from(tokens) + match self.options.data_source { + DataSource::ChimeiRuiju => { + ParsedAddress::from(self.parse_with_chimeiruiju(address).await) + } + DataSource::Geolonia => ParsedAddress::from(self.parse_with_geolonia(address).await), + } } }