Skip to content

Commit

Permalink
Add support for sitelinks (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
lenalebt authored Nov 10, 2023
1 parent ab0a0a8 commit 497ddf9
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wikidata"
version = "0.3.0"
version = "0.3.1"
authors = ["Smitty <me@smitop.com>"]
edition = "2018"
repository = "https://github.com/Smittyvb/wikidata/"
Expand Down
64 changes: 62 additions & 2 deletions src/entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct Entity {
pub labels: BTreeMap<Lang, String>,
/// Known aliases of the item.
pub aliases: BTreeMap<Lang, Vec<String>>,
/// site links (e.g. to wikipedia, wikivoyage, ...)
pub sitelinks: BTreeMap<SiteName, SitelinkValue>,
}

/// The type of entity: normal entity with a Qid, a property with a Pid, or a lexeme with a Lid.
Expand Down Expand Up @@ -184,6 +186,21 @@ pub struct ClaimValue {
pub references: Vec<ReferenceGroup>,
}

/// A site name, as used in the sitelinks.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct SiteName(pub String);

/// A sitelink value.
#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
pub struct SitelinkValue {
/// The title of the site link.
pub title: String,
/// The badges of the article.
pub badges: Vec<Qid>,
/// The url of the article, if present
pub url: Option<String>,
}

impl Entity {
/// All of the values of "instance of" on the entity.
#[must_use]
Expand Down Expand Up @@ -319,6 +336,44 @@ impl Entity {
None => BTreeMap::new(),
};

let sitelinks = match json.get("sitelinks") {
Some(json_map) => {
let json_map = json_map.as_object().ok_or(EntityError::ExpectedObject)?;
let mut map = BTreeMap::new();
for (key, val) in json_map {
let obj = val.as_object().ok_or(EntityError::ExpectedObject)?;
map.insert(
SiteName(key.to_string()),
SitelinkValue {
title: obj
.get("title")
.ok_or(EntityError::ExpectedSiteTitleString)?
.as_str()
.ok_or(EntityError::ExpectedKeyvalTextString)?
.to_string(),
badges: obj
.get("badges")
.ok_or(EntityError::ExpectedSiteBadgesArray)?
.as_array()
.ok_or(EntityError::ExpectedSiteBadgesArray)?
.iter()
.filter_map(|val| {
let raw_id = val
.as_str()
.ok_or(EntityError::ExpectedKeyvalTextString)
.ok()?;
Qid::from_str(raw_id).ok()
})
.collect(),
url: obj.get("url").map(|val| val.to_string()),
},
);
}
map
}
None => BTreeMap::new(),
};

let entity_type = match &json.get("type").ok_or(EntityError::NoEntityType)?.as_str() {
Some("item") => EntityType::Entity,
Some("property") => EntityType::Property,
Expand Down Expand Up @@ -442,6 +497,7 @@ impl Entity {
descriptions,
labels,
aliases,
sitelinks,
})
}
}
Expand Down Expand Up @@ -536,10 +592,14 @@ pub enum EntityError {
ExpectedHashString,
/// A string representing a language was expected but not found
ExpectedLangString,
/// A string repersenting an alias was expected but not found
/// A string representing an alias was expected but not found
ExpectedAliasString,
/// A string reperesnting a Pid was expected but not found
/// A string representing a Pid was expected but not found
ExpectedPidString,
/// A string representing a site title was expected but not found
ExpectedSiteTitleString,
/// An array representing site badges was expected but not found
ExpectedSiteBadgesArray,
/// A mainsnak is missing
MissingMainsnak,
/// An hour/minute/second is out of bounds.
Expand Down

0 comments on commit 497ddf9

Please sign in to comment.