Commit 94b94159 authored by Leonardo Schwarz's avatar Leonardo Schwarz

Add entities::Language

parent 161a76c3
......@@ -10,6 +10,7 @@ default = []
[dependencies]
error-chain = "0.10.0"
isolang = "0.1.1"
regex = "0.2.1"
reqwest_mock = "0.3.0"
rusqlite = { version = "0.12.0", optional = true }
......
use errors::ParseError;
use isolang::Language as IsoLang;
use std::fmt;
use xpath_reader::{FromXml, FromXmlError, XpathReader};
use xpath_reader::reader::FromXmlElement;
/// Represents verbal languages.
#[derive(Clone, Eq, PartialEq)]
pub struct Language {
inner: IsoLang,
}
impl Language {
/// Construct a new instance from an ISO 639-1 language code.
pub fn from_639_1(code: &str) -> Result<Language, ParseError>
{
Ok(Language {
inner: IsoLang::from_639_1(code).ok_or_else(|| {
ParseError::from(format!("Invalid ISO 639-1 code: {}", code))
})?,
})
}
/// Construct a new instance from an ISO 639-3 language code.
///
/// These are used by MusicBrainz internally.
pub fn from_639_3(code: &str) -> Result<Language, ParseError>
{
Ok(Language {
inner: IsoLang::from_639_3(code).ok_or_else(|| {
ParseError::from(format!("Invalid ISO 639-3 code: {}", code))
})?,
})
}
/// Return the ISO 639-1 language code.
pub fn to_639_1(&self) -> Option<&'static str>
{
self.inner.to_639_1()
}
/// Return the ISO 639-3 language code.
pub fn to_639_3(&self) -> &'static str
{
self.inner.to_639_3()
}
}
impl fmt::Debug for Language {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
{
write!(f, "Language [ISO 639-3: {}]", self.to_639_3())
}
}
impl FromXmlElement for Language {}
impl FromXml for Language {
fn from_xml<'d, R>(reader: &'d R) -> Result<Self, FromXmlError>
where
R: XpathReader<'d>,
{
use xpath_reader::errors::ChainXpathErr;
Language::from_639_3(String::from_xml(reader)?.as_str())
.chain_err(|| "Parse Language error")
.map_err(FromXmlError::from)
}
}
// This is needed for it to be able to be used as `SearchField` value.
//
// TODO: Consider whether we should actually create our own trait as `ToString`
// might be a bit
// misleading. Maybe `to_search_value` would be more precise?
impl ToString for Language {
fn to_string(&self) -> String
{
self.to_639_3().to_string()
}
}
......@@ -9,6 +9,9 @@ mod helper;
mod date;
pub use self::date::{FullDate, ParseDateError, PartialDate};
mod lang;
pub use self::lang::Language;
pub mod refs;
pub use self::refs::{AreaRef, ArtistRef, LabelRef, RecordingRef, ReleaseRef};
......@@ -35,7 +38,7 @@ pub use self::release::{LabelInfo, Release, ReleaseMedium, ReleaseStatus, Releas
pub use self::release_group::{ReleaseGroup, ReleaseGroupPrimaryType, ReleaseGroupSecondaryType,
ReleaseGroupType};
// TODO it's pretty useless as of now.
//pub use self::series::Series;
// pub use self::series::Series;
mod mbid;
pub use self::mbid::Mbid;
......
......@@ -2,7 +2,7 @@ use std::time::Duration;
use xpath_reader::{FromXml, FromXmlError, XpathReader};
use xpath_reader::reader::{FromXmlContained, FromXmlElement};
use entities::{Mbid, Resource};
use entities::{Language, Mbid, Resource};
use entities::date::PartialDate;
use entities::refs::{ArtistRef, LabelRef, RecordingRef};
......@@ -182,7 +182,7 @@ pub struct Release {
pub packaging: Option<String>,
/// Language of the release. ISO 639-3 conformant string.
pub language: Option<String>,
pub language: Option<Language>,
/// Script used to write the track list. ISO 15924 conformant string.
pub script: Option<String>,
......@@ -285,7 +285,7 @@ mod tests {
);
assert_eq!(release.barcode, Some("724388023429".to_string()));
assert_eq!(release.status, Some(ReleaseStatus::Official));
assert_eq!(release.language, Some("eng".to_string()));
assert_eq!(release.language, Some(Language::from_639_3("eng").unwrap()));
assert_eq!(release.script, Some("Latn".to_string()));
// TODO: check disambiguation
// assert_eq!(release.disambiguation,
......
......@@ -6,6 +6,7 @@
#[macro_use]
extern crate error_chain;
extern crate isolang;
extern crate regex;
extern crate reqwest_mock;
extern crate uuid;
......
......@@ -96,7 +96,7 @@ define_fields!(
f, Gender, String;
f, IpiCode, String;
f, LabelId, String;
f, Language, String;
f, Language, full_entities::Language;
f, MediumCount, u32;
f, MediumFormat, String;
/// The searched entity's name. (TODO implement for all relevant searches)
......@@ -199,7 +199,7 @@ define_entity_fields!(
define_entity_fields!(
ReleaseSearchField, release;
"arid", ArtistId;
"arid", ArtistMbid;
"artist", ArtistName;
"asin", Asin;
"barcode", Barcode;
......@@ -231,7 +231,7 @@ define_entity_fields!(
define_entity_fields!(
ReleaseGroupSearchField, release_group;
"arid", ArtistId;
"arid", ArtistMbid;
"artist", ArtistCredit;
"artistname", ArtistName;
"comment", Comment;
......
......@@ -8,7 +8,7 @@ use url::percent_encoding::{DEFAULT_ENCODE_SET, utf8_percent_encode};
use xpath_reader::{FromXml, FromXmlError, XpathReader, XpathStrReader};
pub mod fields;
use self::fields::{AreaSearchField, ArtistSearchField, ReleaseSearchField, ReleaseGroupSearchField};
use self::fields::{AreaSearchField, ArtistSearchField, ReleaseGroupSearchField, ReleaseSearchField};
pub mod search_entities;
use self::search_entities::SearchEntity;
......
//! Query builder code.
//!
//! In general you won't need to use any of these types directly, but instead through the
//! In general you won't need to use any of these types directly, but instead
//! through the
//! facilities provided by `Client`.
use super::*;
......@@ -11,8 +12,7 @@ use url::percent_encoding::{DEFAULT_ENCODE_SET, utf8_percent_encode};
/// for a url string.
///
/// This is to be used for attribute values, like for example a release name.
pub(crate)
fn escape_full(text: &str) -> String
pub(crate) fn escape_full(text: &str) -> String
{
// Replace all special lucene syntax elements.
let re = Regex::new(r#"([+\-!\(\)\{\}\[\]\^"~\*\?:\\]|[&\|]{2})"#).unwrap();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment