use errors::Result;
use serde::Serialize;
use std::fmt;
use {CoreFlavor, Diagnostics, Flavor, Loc, Translate, Translator};
#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(bound = "F::Package: Serialize")]
pub struct RpName<F: 'static>
where
F: Flavor,
{
#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<Loc<String>>,
pub package: F::Package,
pub parts: Vec<String>,
}
impl<F: 'static> RpName<F>
where
F: Flavor,
{
pub fn new(prefix: Option<Loc<String>>, package: F::Package, parts: Vec<String>) -> Self {
Self {
prefix: prefix,
package: package,
parts: parts,
}
}
pub fn extend<I>(&self, it: I) -> Self
where
I: IntoIterator<Item = String>,
{
let mut parts = self.parts.clone();
parts.extend(it);
Self {
prefix: self.prefix.clone(),
package: self.package.clone(),
parts: parts,
}
}
pub fn push(&self, part: String) -> Self {
let mut parts = self.parts.clone();
parts.push(part);
Self {
prefix: self.prefix.clone(),
package: self.package.clone(),
parts: parts,
}
}
pub fn join<S: AsRef<str>>(&self, joiner: S) -> String {
self.parts.join(joiner.as_ref())
}
pub fn without_prefix(self) -> Self {
Self {
prefix: None,
package: self.package,
parts: self.parts,
}
}
pub fn with_package(self, package: F::Package) -> Self {
Self {
prefix: self.prefix,
package: package,
parts: self.parts,
}
}
pub fn with_parts(self, parts: Vec<String>) -> Self {
Self {
prefix: self.prefix,
package: self.package,
parts: parts,
}
}
pub fn is_same(&self, other: &Self) -> bool {
self.package == other.package && self.parts == other.parts
}
}
impl RpName<CoreFlavor> {
pub fn without_version(self) -> Self {
Self {
prefix: self.prefix,
package: self.package.without_version(),
parts: self.parts,
}
}
pub fn localize(self) -> Self {
if self.prefix.is_some() {
return self;
}
self.without_version()
}
}
impl<F: 'static> fmt::Display for RpName<F>
where
F: Flavor,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref prefix) = self.prefix {
write!(f, "{}::{}", prefix, self.parts.join("::"))
} else {
write!(f, "{}", self.parts.join("::"))
}
}
}
impl<F: 'static, T> Translate<T> for RpName<F>
where
F: Flavor,
T: Translator<Source = F>,
{
type Source = F;
type Out = RpName<T::Target>;
fn translate(self, _: &mut Diagnostics, translator: &T) -> Result<RpName<T::Target>> {
Ok(RpName {
prefix: self.prefix,
package: translator.translate_package(self.package)?,
parts: self.parts,
})
}
}