use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EntityLink {
pub uri: String,
pub entity_type: EntityType,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub confidence: Option<f64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<KnowledgeBase>,
}
impl EntityLink {
#[must_use]
pub fn new(uri: impl Into<String>, entity_type: EntityType) -> Self {
Self {
uri: uri.into(),
entity_type,
label: None,
confidence: None,
source: None,
}
}
#[must_use]
pub fn with_label(mut self, label: impl Into<String>) -> Self {
self.label = Some(label.into());
self
}
#[must_use]
pub fn with_confidence(mut self, confidence: f64) -> Self {
self.confidence = Some(confidence.clamp(0.0, 1.0));
self
}
#[must_use]
pub fn with_source(mut self, source: KnowledgeBase) -> Self {
self.source = Some(source);
self
}
#[must_use]
pub fn wikipedia(title: impl Into<String>, entity_type: EntityType) -> Self {
let title = title.into();
let uri = format!("https://en.wikipedia.org/wiki/{}", title.replace(' ', "_"));
Self::new(uri, entity_type)
.with_label(title)
.with_source(KnowledgeBase::Wikipedia)
}
#[must_use]
pub fn wikidata(qid: impl Into<String>, entity_type: EntityType) -> Self {
let qid = qid.into();
let uri = format!("https://www.wikidata.org/wiki/{qid}");
Self::new(uri, entity_type).with_source(KnowledgeBase::Wikidata)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, strum::Display)]
#[serde(rename_all = "camelCase")]
#[strum(serialize_all = "kebab-case")]
pub enum EntityType {
Person,
Organization,
Place,
Event,
Product,
CreativeWork,
Concept,
Scientific,
TimePeriod,
Other,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum KnowledgeBase {
Wikipedia,
Wikidata,
Dbpedia,
Schema,
Loc,
Geonames,
Other,
}