Better handling of numbers

This commit is contained in:
Smitty 2021-05-30 11:00:35 -04:00
parent 284af1ad9f
commit c6e0b7745c
3 changed files with 34 additions and 6 deletions

1
items/Q45.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -528,10 +528,18 @@ fn get_json_string(json: Value) -> Result<String, EntityError> {
fn parse_wb_number(num: &Value) -> Result<f64, EntityError> { fn parse_wb_number(num: &Value) -> Result<f64, EntityError> {
match num { match num {
Value::Number(num) => num.as_f64().ok_or(EntityError::NumberOutOfBounds), Value::Number(num) => num.as_f64().ok_or(EntityError::NumberOutOfBounds),
Value::String(s) => match s.parse() { Value::String(s) => {
Ok(x) => Ok(x), // "+1" is a valid Wikibase number
Err(_) => Err(EntityError::FloatParse), let s = if let Some(b'+') = s.bytes().next() {
}, &s[1..]
} else {
&s[..]
};
match s.parse() {
Ok(x) => Ok(x),
Err(_) => Err(EntityError::FloatParse),
}
}
_ => Err(EntityError::ExpectedNumberString), _ => Err(EntityError::ExpectedNumberString),
} }
} }
@ -694,10 +702,11 @@ impl ClaimValueData {
} }
"globecoordinate" => { "globecoordinate" => {
Ok(ClaimValueData::GlobeCoordinate { Ok(ClaimValueData::GlobeCoordinate {
// altitude field is deprecated and we ignore it
lat: parse_wb_number(&take_prop("latitude", &mut value))?, lat: parse_wb_number(&take_prop("latitude", &mut value))?,
lon: parse_wb_number(&take_prop("longitude", &mut value))?, lon: parse_wb_number(&take_prop("longitude", &mut value))?,
// altitude field is deprecated and we ignore it // sometimes precision is missing, default it to 1.0
precision: parse_wb_number(&take_prop("precision", &mut value))?, precision: parse_wb_number(&take_prop("precision", &mut value)).unwrap_or(1.0),
// globe *can* be any IRI, but it practice it's almost always an entity URI // globe *can* be any IRI, but it practice it's almost always an entity URI
// so we return None if it doesn't match our expectations // so we return None if it doesn't match our expectations
globe: try_get_as_qid(&take_prop("globe", &mut value))?, globe: try_get_as_qid(&take_prop("globe", &mut value))?,
@ -842,4 +851,16 @@ mod test {
); );
assert_eq!(qid, Ok(Qid(1234567))); assert_eq!(qid, Ok(Qid(1234567)));
} }
#[test]
fn number_parsing() {
assert_eq!(parse_wb_number(&serde_json::json!("+5")), Ok(5.));
assert_eq!(parse_wb_number(&serde_json::json!("5")), Ok(5.));
assert_eq!(parse_wb_number(&serde_json::json!("-5")), Ok(-5.));
assert_eq!(
parse_wb_number(&serde_json::json!("-81.12683")),
Ok(-81.12683)
);
assert_eq!(parse_wb_number(&serde_json::json!("+0")), Ok(0.));
}
} }

View file

@ -30,3 +30,9 @@ fn mount_everest() {
let j: serde_json::Value = serde_json::from_str(include_str!("../items/Q513.json")).unwrap(); let j: serde_json::Value = serde_json::from_str(include_str!("../items/Q513.json")).unwrap();
Entity::from_json(j).unwrap(); Entity::from_json(j).unwrap();
} }
#[test]
fn portugal() {
let j: serde_json::Value = serde_json::from_str(include_str!("../items/Q45.json")).unwrap();
Entity::from_json(j).unwrap();
}