Skip to content

Commit

Permalink
Merge pull request #246 from YuukiToriyama/release/v0.1.0-beta.16
Browse files Browse the repository at this point in the history
release/v0.1.0-beta.16をmainブランチにマージ
  • Loading branch information
YuukiToriyama authored Apr 28, 2024
2 parents ee68ffd + 62658c2 commit df6ab10
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 59 deletions.
2 changes: 1 addition & 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.0-beta.15"
version = "0.1.0-beta.16"
edition = "2021"
description = "A Rust Library to parse japanese addresses."
repository = "https://github.com/YuukiToriyama/japanese-address-parser"
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,20 @@ Add this to your `Cargo.toml`
cargo add japanese-address-parser
```

### Async Api
### Async Version

```rust
use japanese_address_parser::api::{Api, ApiImpl};
use japanese_address_parser::parser::parse;
use japanese_address_parser::parser::Parser;

#[tokio::main]
async fn main() {
let async_api = ApiImpl::new();
let parse_result = parse(async_api, "東京都千代田区丸の内1-1-1").await;
let parser = Parser::new();
let parse_result = parser.parse("東京都千代田区丸の内1-1-1").await;
println!("{:?}", parse_result);
}
```

### Blocking Api
### Blocking Version

```rust
use japanese_address_parser::api::{BlockingApi, BlockingApiImpl};
Expand Down
35 changes: 9 additions & 26 deletions core/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,15 @@ use crate::api::city_master_api::CityMasterApi;
use crate::api::prefecture_master_api::PrefectureMasterApi;
use crate::entity::{City, Prefecture};
use crate::err::Error;
use std::future::Future;

pub trait Api {
fn new() -> Self;
fn get_prefecture_master(
&self,
prefecture_name: &str,
) -> impl Future<Output = Result<Prefecture, Error>>;
fn get_city_master(
&self,
prefecture_name: &str,
city_name: &str,
) -> impl Future<Output = Result<City, Error>>;
}

pub struct ApiImpl {
pub struct AsyncApi {
pub prefecture_master_api: PrefectureMasterApi,
pub city_master_api: CityMasterApi,
}

impl Api for ApiImpl {
fn new() -> Self {
ApiImpl {
impl AsyncApi {
pub fn new() -> Self {
AsyncApi {
prefecture_master_api: PrefectureMasterApi {
server_url:
"https://yuukitoriyama.github.io/geolonia-japanese-addresses-accompanist",
Expand All @@ -38,19 +24,16 @@ impl Api for ApiImpl {
}
}

fn get_prefecture_master(
&self,
prefecture_name: &str,
) -> impl Future<Output = Result<Prefecture, Error>> {
self.prefecture_master_api.get(prefecture_name)
pub async fn get_prefecture_master(&self, prefecture_name: &str) -> Result<Prefecture, Error> {
self.prefecture_master_api.get(prefecture_name).await
}

fn get_city_master(
pub async fn get_city_master(
&self,
prefecture_name: &str,
city_name: &str,
) -> impl Future<Output = Result<City, Error>> {
self.city_master_api.get(prefecture_name, city_name)
) -> Result<City, Error> {
self.city_master_api.get(prefecture_name, city_name).await
}
}

Expand Down
64 changes: 49 additions & 15 deletions core/src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::api::Api;
use std::sync::Arc;

use crate::api::AsyncApi;
#[cfg(not(target_arch = "wasm32"))]
use crate::api::BlockingApi;
use crate::entity::{Address, ParseResult};
Expand All @@ -14,7 +16,39 @@ mod read_house_number;
mod read_prefecture;
mod read_town;

pub async fn parse<T: Api>(api: T, input: &str) -> ParseResult {
/// An asynchronous `Parser` to process addresses.
///
/// # Example
/// ```
/// use japanese_address_parser::parser::Parser;
///
/// async fn example() {
/// let parser = Parser::new();
/// let result = parser.parse("東京都新宿区西新宿2-8-1").await;
/// println!("{:?}", result);
/// }
/// ```
pub struct Parser {
async_api: Arc<AsyncApi>,
}

impl Parser {
/// Constructs a new `Parser`.
pub fn new() -> Self {
Parser {
async_api: Arc::new(AsyncApi::new()),
}
}
/// Parses the given `address`.
pub async fn parse(&self, address: &str) -> ParseResult {
parse(self.async_api.clone(), address).await
}
}

/// A function to parse the given address.
///
/// publicにしていますが、直接の使用は推奨されません。[Parser]の利用を検討してください。
pub async fn parse(api: Arc<AsyncApi>, input: &str) -> ParseResult {
// 都道府県を特定
let (rest, prefecture_name) = if let Some(result) = read_prefecture(input) {
result
Expand Down Expand Up @@ -73,15 +107,15 @@ pub async fn parse<T: Api>(api: T, input: &str) -> ParseResult {
mod non_blocking_tests {
use crate::api::city_master_api::CityMasterApi;
use crate::api::prefecture_master_api::PrefectureMasterApi;
use crate::api::{Api, ApiImpl};
use crate::api::AsyncApi;
use crate::err::ParseErrorKind;
use crate::parser::parse;
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};

#[tokio::test]
async fn 都道府県名が誤っている場合() {
let api = ApiImpl::new();
let result = parse(api, "青盛県青森市長島1丁目1−1").await;
let api = AsyncApi::new();
let result = parse(api.into(), "青盛県青森市長島1丁目1−1").await;
assert_eq!(result.address.prefecture, "");
assert_eq!(result.address.city, "");
assert_eq!(result.address.town, "");
Expand All @@ -95,12 +129,12 @@ mod non_blocking_tests {

#[tokio::test]
async fn 都道府県マスタが取得できない場合() {
let mut api = ApiImpl::new();
let mut api = AsyncApi::new();
api.prefecture_master_api = PrefectureMasterApi {
server_url: "https://example.com/invalid_url/api/",
};

let result = parse(api, "青森県青森市長島1丁目1−1").await;
let result = parse(api.into(), "青森県青森市長島1丁目1−1").await;
assert_eq!(result.error.is_some(), true);
assert_eq!(result.address.prefecture, "青森県");
assert_eq!(result.address.city, "");
Expand All @@ -110,8 +144,8 @@ mod non_blocking_tests {

#[tokio::test]
async fn 市区町村名が誤っている場合() {
let api = ApiImpl::new();
let result = parse(api, "青森県青盛市長島1丁目1−1").await;
let api = AsyncApi::new();
let result = parse(api.into(), "青森県青盛市長島1丁目1−1").await;
assert_eq!(result.address.prefecture, "青森県");
assert_eq!(result.address.city, "");
assert_eq!(result.address.town, "");
Expand All @@ -125,12 +159,12 @@ mod non_blocking_tests {

#[tokio::test]
async fn 市区町村マスタが取得できない場合() {
let mut api = ApiImpl::new();
let mut api = AsyncApi::new();
api.city_master_api = CityMasterApi {
server_url: "https://example.com/invalid_url/api/",
};

let result = parse(api, "青森県青森市長島1丁目1−1").await;
let result = parse(api.into(), "青森県青森市長島1丁目1−1").await;
assert_eq!(result.error.is_some(), true);
assert_eq!(result.address.prefecture, "青森県");
assert_eq!(result.address.city, "青森市");
Expand All @@ -140,8 +174,8 @@ mod non_blocking_tests {

#[tokio::test]
async fn 町名が誤っている場合() {
let api = ApiImpl::new();
let result = parse(api, "青森県青森市永嶋1丁目1−1").await;
let api = AsyncApi::new();
let result = parse(api.into(), "青森県青森市永嶋1丁目1−1").await;
assert_eq!(result.address.prefecture, "青森県");
assert_eq!(result.address.city, "青森市");
assert_eq!(result.address.town, "");
Expand All @@ -157,8 +191,8 @@ mod non_blocking_tests {

#[wasm_bindgen_test]
async fn parse_wasm_success() {
let api = ApiImpl::new();
let result = parse(api, "兵庫県淡路市生穂新島8番地").await;
let api = AsyncApi::new();
let result = parse(api.into(), "兵庫県淡路市生穂新島8番地").await;
assert_eq!(result.address.prefecture, "兵庫県".to_string());
assert_eq!(result.address.city, "淡路市".to_string());
assert_eq!(result.address.town, "生穂".to_string());
Expand Down
7 changes: 3 additions & 4 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use csv::ReaderBuilder;
use japanese_address_parser::api::{Api, ApiImpl};
use japanese_address_parser::parser::parse;
use japanese_address_parser::parser::Parser;
use serde::Deserialize;
use std::fs::File;
use std::panic;
Expand Down Expand Up @@ -28,9 +27,9 @@ fn read_test_data_from_csv(file_path: &str) -> Result<Vec<Record>, &str> {
pub async fn run_data_driven_tests(file_path: &str) {
let records = read_test_data_from_csv(file_path).unwrap();
let mut success_count = 0;
let parser = Parser::new();
for record in &records {
let api = ApiImpl::new();
let result = parse(api, &record.address).await;
let result = parser.parse(&record.address).await;

let test_result = panic::catch_unwind(|| {
assert_eq!(result.address.prefecture, record.prefecture);
Expand Down
18 changes: 11 additions & 7 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use japanese_address_parser::api::{Api, ApiImpl};
use japanese_address_parser::api::AsyncApi;
use japanese_address_parser::parser;
use std::sync::Arc;
use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::JsValue;

Expand Down Expand Up @@ -30,20 +31,23 @@ export class Parser {
}"#;

#[wasm_bindgen(skip_typescript)]
pub struct Parser();
pub struct Parser {
async_api: Arc<AsyncApi>,
}

#[wasm_bindgen]
impl Parser {
#[wasm_bindgen(constructor)]
pub fn new() -> Self {
Parser {}
#[cfg(feature = "debug")]
console_error_panic_hook::set_once();
Parser {
async_api: Arc::new(AsyncApi::new()),
}
}

pub async fn parse(&self, address: &str) -> JsValue {
#[cfg(feature = "debug")]
console_error_panic_hook::set_once();
let api = ApiImpl::new();
let result = parser::parse(api, address).await;
let result = parser::parse(self.async_api.clone(), address).await;
serde_wasm_bindgen::to_value(&result).unwrap()
}
}

0 comments on commit df6ab10

Please sign in to comment.