use serde::Serialize;
#[derive(Debug, Clone, Default, PartialEq, Serialize)]
pub struct HojinSearchQuery {
#[serde(skip_serializing_if = "Option::is_none")]
pub corporate_number: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exist_flg: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub corporate_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub prefecture: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub city: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub capital_stock_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub capital_stock_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub employee_number_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub employee_number_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub founded_year: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub net_sales_summary_of_business_results_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub net_sales_summary_of_business_results_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_assets_summary_of_business_results_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub total_assets_summary_of_business_results_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_continuous_service_years: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub average_age: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub month_average_predetermined_overtime_hours: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub female_workers_proportion: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub patent: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub procurement: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub procurement_amount_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub procurement_amount_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subsidy: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subsidy_amount_from: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subsidy_amount_to: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub certification: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ministry: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata_flg: Option<bool>,
}
impl HojinSearchQuery {
pub fn new() -> Self {
Self::default()
}
pub fn corporate_number(mut self, value: impl Into<String>) -> Self {
self.corporate_number = Some(value.into());
self
}
pub fn name(mut self, value: impl Into<String>) -> Self {
self.name = Some(value.into());
self
}
pub fn exist_flg(mut self, value: bool) -> Self {
self.exist_flg = Some(value);
self
}
pub fn corporate_type(mut self, value: impl Into<String>) -> Self {
self.corporate_type = Some(value.into());
self
}
pub fn prefecture(mut self, value: impl Into<String>) -> Self {
self.prefecture = Some(value.into());
self
}
pub fn city(mut self, value: impl Into<String>) -> Self {
self.city = Some(value.into());
self
}
pub fn capital_stock(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.capital_stock_from = from;
self.capital_stock_to = to;
self
}
pub fn employee_number(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.employee_number_from = from;
self.employee_number_to = to;
self
}
pub fn founded_year(mut self, value: impl Into<String>) -> Self {
self.founded_year = Some(value.into());
self
}
pub fn net_sales(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.net_sales_summary_of_business_results_from = from;
self.net_sales_summary_of_business_results_to = to;
self
}
pub fn total_assets(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.total_assets_summary_of_business_results_from = from;
self.total_assets_summary_of_business_results_to = to;
self
}
pub fn average_continuous_service_years(mut self, value: impl Into<String>) -> Self {
self.average_continuous_service_years = Some(value.into());
self
}
pub fn average_age(mut self, value: impl Into<String>) -> Self {
self.average_age = Some(value.into());
self
}
pub fn month_average_predetermined_overtime_hours(mut self, value: impl Into<String>) -> Self {
self.month_average_predetermined_overtime_hours = Some(value.into());
self
}
pub fn female_workers_proportion(mut self, value: impl Into<String>) -> Self {
self.female_workers_proportion = Some(value.into());
self
}
pub fn patent(mut self, value: impl Into<String>) -> Self {
self.patent = Some(value.into());
self
}
pub fn procurement(mut self, value: impl Into<String>) -> Self {
self.procurement = Some(value.into());
self
}
pub fn procurement_amount(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.procurement_amount_from = from;
self.procurement_amount_to = to;
self
}
pub fn subsidy(mut self, value: impl Into<String>) -> Self {
self.subsidy = Some(value.into());
self
}
pub fn subsidy_amount(mut self, from: Option<u64>, to: Option<u64>) -> Self {
self.subsidy_amount_from = from;
self.subsidy_amount_to = to;
self
}
pub fn certification(mut self, value: impl Into<String>) -> Self {
self.certification = Some(value.into());
self
}
pub fn ministry(mut self, value: impl Into<String>) -> Self {
self.ministry = Some(value.into());
self
}
pub fn source(mut self, value: impl Into<String>) -> Self {
self.source = Some(value.into());
self
}
pub fn page(mut self, value: u32) -> Self {
self.page = Some(value);
self
}
pub fn limit(mut self, value: u32) -> Self {
self.limit = Some(value);
self
}
pub fn metadata_flg(mut self, value: bool) -> Self {
self.metadata_flg = Some(value);
self
}
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct UpdateInfoQuery {
pub from: String,
pub to: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata_flg: Option<bool>,
}
impl UpdateInfoQuery {
pub fn new(from: impl Into<String>, to: impl Into<String>) -> Self {
Self {
from: from.into(),
to: to.into(),
page: None,
metadata_flg: None,
}
}
pub fn page(mut self, value: u32) -> Self {
self.page = Some(value);
self
}
pub fn metadata_flg(mut self, value: bool) -> Self {
self.metadata_flg = Some(value);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::{json, Value};
#[test]
fn search_query_skips_unset_fields() {
let query = HojinSearchQuery::new();
let value = serde_json::to_value(&query).unwrap();
assert_eq!(value, json!({}));
}
#[test]
fn search_query_serializes_set_fields() {
let query = HojinSearchQuery::new()
.name("トヨタ自動車")
.corporate_type("301")
.exist_flg(true)
.capital_stock(Some(1_000_000), None)
.page(1)
.limit(100)
.metadata_flg(false);
let value = serde_json::to_value(&query).unwrap();
assert_eq!(
value,
json!({
"name": "トヨタ自動車",
"corporate_type": "301",
"exist_flg": true,
"capital_stock_from": 1_000_000,
"page": 1,
"limit": 100,
"metadata_flg": false,
})
);
}
#[test]
fn search_query_all_fields_serialize() {
let query = HojinSearchQuery::new()
.corporate_number("1180301018771")
.name("n")
.exist_flg(true)
.corporate_type("301")
.prefecture("23")
.city("211")
.capital_stock(Some(1), Some(2))
.employee_number(Some(3), Some(4))
.founded_year("1937,1938")
.net_sales(Some(5), Some(6))
.total_assets(Some(7), Some(8))
.average_continuous_service_years("A")
.average_age("B")
.month_average_predetermined_overtime_hours("C")
.female_workers_proportion("D")
.patent("p")
.procurement("q")
.procurement_amount(Some(9), Some(10))
.subsidy("s")
.subsidy_amount(Some(11), Some(12))
.certification("c")
.ministry("100,200")
.source("1,6")
.page(2)
.limit(500)
.metadata_flg(true);
let value = serde_json::to_value(&query).unwrap();
let Value::Object(map) = value else {
panic!("object expected")
};
assert_eq!(map.len(), 32);
}
#[test]
fn update_info_query_serializes() {
let query = UpdateInfoQuery::new("20260401", "20260430");
let value = serde_json::to_value(&query).unwrap();
assert_eq!(value, json!({"from": "20260401", "to": "20260430"}));
let query = UpdateInfoQuery::new("20260401", "20260430")
.page(2)
.metadata_flg(true);
let value = serde_json::to_value(&query).unwrap();
assert_eq!(
value,
json!({"from": "20260401", "to": "20260430", "page": 2, "metadata_flg": true})
);
}
}