From e9cd90efff208ac82923fe59de93a724cb7117e1 Mon Sep 17 00:00:00 2001 From: Dashiell Stander Date: Mon, 26 Jul 2021 23:12:16 -0700 Subject: [PATCH] Added new field on Entity struct that has the ID on it Co-authored-by: Smittyvb --- src/entity.rs | 42 ++++++++++++++++++++++++++++++++++++++- tests/entity-from-json.rs | 3 ++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/entity.rs b/src/entity.rs index 1c51454..04b9a8b 100755 --- a/src/entity.rs +++ b/src/entity.rs @@ -1,6 +1,6 @@ use std::{collections::BTreeMap, str::FromStr}; -use crate::ids::{consts, Fid, Lid, Pid, Qid, Sid}; +use crate::ids::{consts, Fid, IdParseError, Lid, Pid, Qid, Sid}; use crate::text::{Lang, Text}; use chrono::{DateTime, TimeZone, Utc}; use serde::{Deserialize, Serialize}; @@ -9,6 +9,8 @@ use serde_json::Value; /// A Wikibase entity: this could be an entity, property, or lexeme. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct Entity { + ///Unique identifier + pub id: WikiId, /// All of the claims on the entity. pub claims: Vec<(Pid, ClaimValue)>, /// The type of the entity. @@ -21,6 +23,17 @@ pub struct Entity { pub aliases: BTreeMap>, } +/// Three main types of IDs entities can have. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum WikiId { + /// A Qid + EntityId(Qid), + /// A Pid + PropertyId(Pid), + /// An Lid + LexemeId(Lid), +} + /// The type of entity: normal entity with a Qid, a property with a Pid, or a lexeme with a Lid. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[non_exhaustive] @@ -238,6 +251,17 @@ impl Entity { None => json, }; + let raw_id: &str = json + .get_mut("id") + .ok_or(EntityError::ExpectedObject)? + .as_str() + .ok_or(EntityError::ExpectedKeyvalTextString)?; + + let id: WikiId = match get_wiki_id(raw_id) { + Ok(id) => id, + _ => return Err(EntityError::NoId), + }; + macro_rules! text_keyval { ($key:literal) => {{ match json.get($key) { @@ -412,6 +436,7 @@ impl Entity { } Ok(Self { + id, claims, entity_type, descriptions, @@ -421,6 +446,16 @@ impl Entity { } } +fn get_wiki_id(id: &str) -> Result { + let uid: WikiId = match &id[0..1] { + "Q" => WikiId::EntityId(Qid::from_str(id).unwrap()), + "P" => WikiId::PropertyId(Pid::from_str(id).unwrap()), + "L" => WikiId::LexemeId(Lid::from_str(id).unwrap()), + _ => return Err(IdParseError::InvalidPrefix), + }; + Ok(uid) +} + /// An error related to entity parsing/creation. #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] @@ -852,6 +887,11 @@ mod test { assert_eq!(qid, Ok(Qid(1234567))); } + #[test] + fn get_wiki_id_test() { + assert_eq!(get_wiki_id("Q42").unwrap(), WikiId::EntityId(Qid(42))); + } + #[test] fn number_parsing() { assert_eq!(parse_wb_number(&serde_json::json!("+5")), Ok(5.)); diff --git a/tests/entity-from-json.rs b/tests/entity-from-json.rs index 230cca7..08806ea 100644 --- a/tests/entity-from-json.rs +++ b/tests/entity-from-json.rs @@ -10,7 +10,8 @@ fn simple_item() { #[test] fn douglas_adams() { let j: serde_json::Value = serde_json::from_str(include_str!("../items/Q42.json")).unwrap(); - Entity::from_json(j).unwrap(); + let e = Entity::from_json(j).unwrap(); + assert_eq!(e.id, WikiId::EntityId(Qid(42))); } #[test]