Skip to content
Snippets Groups Projects
Commit d762365a authored by Nathan Ringo's avatar Nathan Ringo
Browse files

Adds uri_fragment method.

parent f0aef154
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,7 @@ use parser::{parse, ParseError};
use serde_json::Value;
use std::fmt::{Display, Formatter};
use std::fmt::Result as FmtResult;
use std::fmt::Write;
use std::marker::PhantomData;
use std::ops::{Index, IndexMut};
use std::str::FromStr;
......@@ -94,6 +95,30 @@ impl<S: AsRef<str>, C: AsRef<[S]>> JsonPointer<S, C> {
}
}))
}
/// Converts a JSON pointer to a string in URI Fragment Identifier
/// Representation, including the leading `#`.
pub fn uri_fragment(&self) -> String {
fn legal_fragment_byte(b: u8) -> bool {
match b {
0x21 | 0x24 | 0x26...0x3b | 0x3d | 0x3f...0x5a | 0x5f | 0x61...0x7a => true,
_ => false,
}
}
let mut s = "#".to_string();
for part in self.ref_toks.as_ref().iter() {
s += "/";
for b in part.as_ref().bytes() {
if legal_fragment_byte(b) {
s.push(b as char)
} else {
write!(s, "%{:02x}", b).unwrap()
}
}
}
s
}
}
impl<S: AsRef<str>> JsonPointer<S, Vec<S>> {
......
......@@ -11,20 +11,20 @@ use regex::Regex;
quickcheck! {
/// Essentially, `unparse(parse("..."))` should be a no-op when not in URI
/// Fragment Identifier Representation.
/// Essentially, `unparse(parse("..."))` should be a no-op.
fn faithful_parse(s: String) -> TestResult {
if s.chars().next() == Some('#') {
TestResult::discard()
let ok = match s.parse::<JsonPointer<_, _>>() {
Ok(ptr) => if s.chars().next() == Some('#') {
(s == ptr.uri_fragment())
} else {
(s == ptr.to_string())
},
Err(_) => return TestResult::discard(),
};
if ok {
TestResult::passed()
} else {
match s.parse::<JsonPointer<_, _>>() {
Ok(ptr) => if s == ptr.to_string() {
TestResult::passed()
} else {
TestResult::failed()
},
Err(_) => TestResult::discard(),
}
TestResult::failed()
}
}
......@@ -33,7 +33,7 @@ fn faithful_parse(s: String) -> TestResult {
fn parses_all_valid(s: String) -> bool {
lazy_static! {
static ref JSON_POINTER_REGEX: Regex = Regex::new("^(/([^/~]|~[01])*)*$").unwrap();
static ref URI_FRAGMENT_REGEX: Regex = Regex::new("^#(/([^/~%]|~[01]|%[0-9a-fA-F]{2})*)*$").unwrap();
static ref URI_FRAGMENT_REGEX: Regex = Regex::new("^#(/([^A-Za-z0-9._!$&'()*+,;=@/?-]|~[01]|%[0-9a-fA-F]{2})*)*$").unwrap();
}
let matches_regex = JSON_POINTER_REGEX.is_match(&s) || URI_FRAGMENT_REGEX.is_match(&s);
......
extern crate json_pointer;
use json_pointer::JsonPointer;
macro_rules! assert_unparse {
($expr:expr) => {
let ptr = $expr.parse::<JsonPointer<_, _>>().unwrap();
assert_eq!(ptr.uri_fragment(), $expr);
};
}
#[test]
fn uri_fragment_unparses() {
assert_unparse!("#/");
assert_unparse!("#/per%25/%25cent");
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment