1use errors::Result;
4use serde::Serialize;
5use std::fmt;
6use {CoreFlavor, Diagnostics, Flavor, Loc, Translate, Translator};
7
8#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
9#[serde(bound = "F::Package: Serialize")]
10pub struct RpName<F: 'static>
11where
12 F: Flavor,
13{
14 #[serde(skip_serializing_if = "Option::is_none")]
16 pub prefix: Option<Loc<String>>,
17 pub package: F::Package,
19 pub parts: Vec<String>,
21}
22
23impl<F: 'static> RpName<F>
24where
25 F: Flavor,
26{
27 pub fn new(prefix: Option<Loc<String>>, package: F::Package, parts: Vec<String>) -> Self {
28 Self {
29 prefix: prefix,
30 package: package,
31 parts: parts,
32 }
33 }
34
35 pub fn extend<I>(&self, it: I) -> Self
36 where
37 I: IntoIterator<Item = String>,
38 {
39 let mut parts = self.parts.clone();
40 parts.extend(it);
41
42 Self {
43 prefix: self.prefix.clone(),
44 package: self.package.clone(),
45 parts: parts,
46 }
47 }
48
49 pub fn push(&self, part: String) -> Self {
50 let mut parts = self.parts.clone();
51 parts.push(part);
52
53 Self {
54 prefix: self.prefix.clone(),
55 package: self.package.clone(),
56 parts: parts,
57 }
58 }
59
60 pub fn join<S: AsRef<str>>(&self, joiner: S) -> String {
61 self.parts.join(joiner.as_ref())
62 }
63
64 pub fn without_prefix(self) -> Self {
66 Self {
67 prefix: None,
68 package: self.package,
69 parts: self.parts,
70 }
71 }
72
73 pub fn with_package(self, package: F::Package) -> Self {
74 Self {
75 prefix: self.prefix,
76 package: package,
77 parts: self.parts,
78 }
79 }
80
81 pub fn with_parts(self, parts: Vec<String>) -> Self {
83 Self {
84 prefix: self.prefix,
85 package: self.package,
86 parts: parts,
87 }
88 }
89
90 pub fn is_same(&self, other: &Self) -> bool {
91 self.package == other.package && self.parts == other.parts
92 }
93}
94
95impl RpName<CoreFlavor> {
96 pub fn without_version(self) -> Self {
98 Self {
99 prefix: self.prefix,
100 package: self.package.without_version(),
101 parts: self.parts,
102 }
103 }
104
105 pub fn localize(self) -> Self {
109 if self.prefix.is_some() {
110 return self;
111 }
112
113 self.without_version()
114 }
115}
116
117impl<F: 'static> fmt::Display for RpName<F>
118where
119 F: Flavor,
120{
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 if let Some(ref prefix) = self.prefix {
123 write!(f, "{}::{}", prefix, self.parts.join("::"))
124 } else {
125 write!(f, "{}", self.parts.join("::"))
126 }
127 }
128}
129
130impl<F: 'static, T> Translate<T> for RpName<F>
131where
132 F: Flavor,
133 T: Translator<Source = F>,
134{
135 type Source = F;
136 type Out = RpName<T::Target>;
137
138 fn translate(self, _: &mut Diagnostics, translator: &T) -> Result<RpName<T::Target>> {
140 Ok(RpName {
141 prefix: self.prefix,
142 package: translator.translate_package(self.package)?,
143 parts: self.parts,
144 })
145 }
146}