wikibase 0.7.6

A library to access Wikibase
Documentation
// from_json.rs
//
// Copyright © 2018
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

extern crate serde_json;

//use std::str::FromStr;
use {
    crate::Entity, crate::EntityType, crate::LocaleString, crate::SearchQuery,
    crate::SearchResultEntity, crate::SearchResults, crate::WikibaseError,
};

/// Deserializes a Wikibase entity from JSON
///
/// Takes a serde JSON value and deserializes the complete data into a Rust
/// native data structure.
pub fn entity_from_json(json: &serde_json::Value) -> Result<Entity, WikibaseError> {
    Entity::new_from_json(json)
}

/// Search result entity from JSON
///
/// Takes a serde JSON value of search results and deserializes it. Returns a
/// vector of results or an error.
pub fn search_result_entities_from_json(
    json: &serde_json::Value,
    query: &SearchQuery,
) -> Result<SearchResults, WikibaseError> {
    let results_json = match json["search"].as_array() {
        Some(value) => value,
        None => {
            return Err(WikibaseError::Serialization(
                "No search results".to_string(),
            ));
        }
    };
    let mut results = vec![];

    for result in results_json {
        results.push(search_result_entity_from_json(result, query)?);
    }

    Ok(SearchResults::new(results))
}

/// Creates a search result entity from JSON
///
/// The locale of the texts is the same as the `uselang` parameter in the
/// request URL.
fn search_result_entity_from_json(
    result_json: &serde_json::Value,
    query: &SearchQuery,
) -> Result<SearchResultEntity, WikibaseError> {
    let id = match result_json["id"].as_str() {
        Some(value) => value,
        None => return Err(WikibaseError::Serialization("Search result ID".to_string())),
    };
    let label_text = match result_json["label"].as_str() {
        Some(value) => value,
        None => {
            return Err(WikibaseError::Serialization(
                "Search result label".to_string(),
            ));
        }
    };
    let label = LocaleString::new("en", label_text);
    let description = result_json["description"]
        .as_str()
        .map(|value| LocaleString::new("en", value));
    let aliases = aliases_from_json(result_json, query)?;
    let entity_type = EntityType::new_from_id(id)?;

    Ok(SearchResultEntity::new(
        id,
        entity_type,
        label,
        description,
        aliases,
    ))
}

/// Alias from JSON
///
/// Takes a serde JSON value and deserializes the aliases into a vector of
/// LocaleStrings.
fn aliases_from_json(
    json_value: &serde_json::Value,
    query: &SearchQuery,
) -> Result<Vec<LocaleString>, WikibaseError> {
    let aliases_array = match json_value.get("aliases") {
        Some(value) => match value.as_array() {
            Some(value_array) => value_array,
            None => return Err(WikibaseError::Serialization("Aliases array".to_string())),
        },
        None => return Ok(vec![]),
    };

    let mut aliases = vec![];

    for alias in aliases_array.iter() {
        match alias.as_str() {
            Some(value) => aliases.push(LocaleString::new(query.search_lang(), value)),
            None => return Err(WikibaseError::Serialization("Aliases string".to_string())),
        };
    }

    Ok(aliases)
}

/// Serializes a numeric value to a f64 option
///
/// Takes a value of the following structure:
/// {"key": "4"}
pub fn float_from_json(
    value: &serde_json::Map<String, serde_json::Value>,
    key: &str,
) -> Option<f64> {
    let single_value = value.get(key)?;
    if let Some(v) = single_value.as_f64() {
        return Some(v);
    }
    let value_string = single_value.as_str()?;
    value_string.parse().ok()
}