Include the namespace-separating solidus in NamespaceableName.
This commit is contained in:
parent
e4447927c7
commit
98bc465a8e
2 changed files with 29 additions and 14 deletions
|
@ -32,11 +32,12 @@ use serde::ser::{
|
|||
#[derive(Clone, Eq, Hash, PartialEq)]
|
||||
pub struct NamespaceableName {
|
||||
// The bytes that make up the namespace followed directly by those
|
||||
// that make up the name.
|
||||
// that make up the name. If there is a namespace, a solidus ('/') is between
|
||||
// the two parts.
|
||||
components: String,
|
||||
|
||||
// The index (in bytes) into `components` where the namespace ends and
|
||||
// name begins.
|
||||
// The index (in bytes) into `components` of the dividing solidus — the place
|
||||
// where the namespace ends and the name begins.
|
||||
//
|
||||
// If this is zero, it means that this is _not_ a namespaced value!
|
||||
//
|
||||
|
@ -79,6 +80,7 @@ impl NamespaceableName {
|
|||
let mut dest = String::with_capacity(n.len() + ns.len());
|
||||
|
||||
dest.push_str(ns);
|
||||
dest.push('/');
|
||||
dest.push_str(n);
|
||||
|
||||
let boundary = ns.len();
|
||||
|
@ -135,13 +137,19 @@ impl NamespaceableName {
|
|||
if self.boundary == 0 {
|
||||
&self.components
|
||||
} else {
|
||||
&self.components[self.boundary..]
|
||||
&self.components[(self.boundary + 1)..]
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn components<'a>(&'a self) -> (&'a str, &'a str) {
|
||||
self.components.split_at(self.boundary)
|
||||
if self.boundary > 0 {
|
||||
(&self.components[0..self.boundary],
|
||||
&self.components[(self.boundary + 1)..])
|
||||
} else {
|
||||
(&self.components[0..0],
|
||||
&self.components)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +185,12 @@ impl fmt::Debug for NamespaceableName {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for NamespaceableName {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&self.components)
|
||||
}
|
||||
}
|
||||
|
||||
// This is convoluted, but the basic idea is that since we don't want to rely on our input being
|
||||
// correct, we'll need to implement a custom serializer no matter what (e.g. we can't just
|
||||
// `derive(Deserialize)` since `unsafe` code depends on `self.boundary` being a valid index).
|
||||
|
|
|
@ -8,7 +8,12 @@
|
|||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::fmt::{
|
||||
Display,
|
||||
Formatter,
|
||||
Write,
|
||||
};
|
||||
|
||||
use namespaceable_name::NamespaceableName;
|
||||
|
||||
#[macro_export]
|
||||
|
@ -264,7 +269,7 @@ impl Display for PlainSymbol {
|
|||
/// assert_eq!("baz", PlainSymbol::plain("baz").to_string());
|
||||
/// ```
|
||||
fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
|
||||
write!(f, "{}", self.0)
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +283,7 @@ impl Display for NamespacedSymbol {
|
|||
/// assert_eq!("bar/baz", NamespacedSymbol::namespaced("bar", "baz").to_string());
|
||||
/// ```
|
||||
fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
|
||||
write!(f, "{}/{}", self.namespace(), self.name())
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,12 +300,8 @@ impl Display for Keyword {
|
|||
/// assert_eq!(":bar/baz", Keyword::namespaced("bar", "baz").to_reversed().to_reversed().to_string());
|
||||
/// ```
|
||||
fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
|
||||
if self.0.is_namespaced() {
|
||||
let (ns, name) = self.0.components();
|
||||
write!(f, ":{}/{}", ns, name)
|
||||
} else {
|
||||
write!(f, ":{}", self.0.name())
|
||||
}
|
||||
f.write_char(':')?;
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue