use serde::{Deserialize, Serialize};
use serde_json::Value;
fn deserialize_null_as_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
D: serde::Deserializer<'de>,
T: serde::Deserialize<'de> + Default,
{
Ok(Option::<T>::deserialize(deserializer)?.unwrap_or_default())
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResponse {
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub results: Vec<SearchHit>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sort: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchHit {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub identifier: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub slug: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub publisher: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub organization: Option<Organization>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub keyword: Vec<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub theme: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub has_spatial: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub popularity: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub last_harvested_date: Option<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub distribution_titles: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub harvest_record: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub harvest_record_raw: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub spatial_centroid: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub spatial_shape: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dcat: Option<Dataset>,
#[serde(default, rename = "_score", skip_serializing_if = "Option::is_none")]
pub score: Option<f64>,
#[serde(default, rename = "_sort", skip_serializing_if = "Option::is_none")]
pub sort_key: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Dataset {
#[serde(default, rename = "@type", skip_serializing_if = "Option::is_none")]
pub type_hint: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub identifier: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "accessLevel"
)]
pub access_level: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub modified: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub issued: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub publisher: Option<Publisher>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "contactPoint"
)]
pub contact_point: Option<ContactPoint>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub keyword: Vec<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub theme: Vec<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub distribution: Vec<Distribution>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "landingPage"
)]
pub landing_page: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub license: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub rights: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub spatial: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub temporal: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "accrualPeriodicity"
)]
pub accrual_periodicity: Option<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub language: Vec<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "bureauCode"
)]
pub bureau_code: Option<Value>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "programCode"
)]
pub program_code: Option<Value>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "describedBy"
)]
pub described_by: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "describedByType"
)]
pub described_by_type: Option<String>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub references: Vec<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "dataQuality"
)]
pub data_quality: Option<bool>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "systemOfRecords"
)]
pub system_of_records: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Distribution {
#[serde(default, rename = "@type", skip_serializing_if = "Option::is_none")]
pub type_hint: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub title: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "downloadURL"
)]
pub download_url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "accessURL")]
pub access_url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "mediaType")]
pub media_type: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub format: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub license: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "describedBy"
)]
pub described_by: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "describedByType"
)]
pub described_by_type: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Publisher {
#[serde(default, rename = "@type", skip_serializing_if = "Option::is_none")]
pub type_hint: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
rename = "subOrganizationOf"
)]
pub sub_organization_of: Option<Box<Publisher>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContactPoint {
#[serde(default, rename = "@type", skip_serializing_if = "Option::is_none")]
pub type_hint: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fn_: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "hasEmail")]
pub has_email: Option<String>,
}
impl ContactPoint {
pub fn with_name(name: impl Into<String>) -> Self {
Self {
type_hint: None,
fn_: Some(name.into()),
has_email: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrganizationsResponse {
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub organizations: Vec<Organization>,
#[serde(default)]
pub total: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Organization {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub slug: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub logo: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub organization_type: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dataset_count: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_count: Option<i64>,
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub aliases: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeywordsResponse {
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub keywords: Vec<KeywordCount>,
#[serde(default)]
pub total: i64,
#[serde(default)]
pub size: i64,
#[serde(default)]
pub min_count: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeywordCount {
pub keyword: String,
pub count: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LocationsResponse {
#[serde(default, deserialize_with = "deserialize_null_as_default")]
pub locations: Vec<Location>,
#[serde(default)]
pub total: i64,
#[serde(default)]
pub size: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Location {
pub id: String,
pub display_name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HarvestRecord {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ckan_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub identifier: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub parent_identifier: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub harvest_job_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub harvest_source_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub action: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub status: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub date_created: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub date_finished: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_hash: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_raw: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_transform: Option<Value>,
}