Skip to content

Commit

Permalink
Merge pull request #26 from asmello/main
Browse files Browse the repository at this point in the history
`Pointer::pop_front`: Correctly handle empty strings
  • Loading branch information
chanced authored Mar 18, 2024
2 parents 5e48cf4 + dcb50f9 commit 8335883
Showing 1 changed file with 60 additions and 19 deletions.
79 changes: 60 additions & 19 deletions src/pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,19 @@ impl Pointer {
}
/// Removes and returns the first `Token` in the `Pointer` if it exists.
pub fn pop_front(&mut self) -> Option<Token> {
if self.inner.is_empty() {
return None;
}
if self.count > 0 {
(!self.inner.is_empty() && self.count > 0).then(|| {
self.count -= 1;
}

self.inner[1..]
.split_once('/')
.map_or(Some((&self.inner[1..], "")), Option::Some)
.map(|(f, b)| (f.to_owned(), b.to_owned()))
.map(|(front, back)| {
if !back.is_empty() {
self.inner = String::from("/") + &back;
} else {
self.inner = String::new()
}
front.into()
})
if let Some((front, back)) = self.inner[1..].split_once('/') {
let front = Token::from_encoded(front);
self.inner = String::from("/") + back;
front
} else {
let token = Token::from_encoded(&self.inner[1..]);
self.inner.truncate(0);
token
}
})
}
/// Returns the number of tokens in the `Pointer`.
pub fn count(&self) -> usize {
Expand Down Expand Up @@ -220,8 +214,11 @@ impl Pointer {
}
self.inner[1..]
.split_once('/')
.map_or(Some((&self.inner[1..], "")), Option::Some)
.map(|(front, _)| Token::from_encoded(front))
.map_or_else(
|| Token::from_encoded(&self.inner[1..]),
|(front, _)| Token::from_encoded(front),
)
.into()
}
/// Returns the first `Token` in the `Pointer`.
///
Expand Down Expand Up @@ -1368,6 +1365,50 @@ mod tests {
assert_eq!(ptr, "");
}

#[test]
fn pop_front_works_with_empty_strings() {
{
let mut ptr = Pointer::new(["bar", "", ""]);

assert_eq!(ptr.tokens().count(), 3);
let mut token = ptr.pop_front();
assert_eq!(token, Some(Token::from_encoded("bar")));
assert_eq!(ptr.tokens().count(), 2);
token = ptr.pop_front();
assert_eq!(token, Some(Token::from_encoded("")));
assert_eq!(ptr.tokens().count(), 1);
token = ptr.pop_front();
assert_eq!(token, Some(Token::from_encoded("")));
assert_eq!(ptr.tokens().count(), 0);
assert_eq!(ptr, Pointer::root());
}
{
let mut ptr = Pointer::root();
assert_eq!(ptr.tokens().count(), 0);
ptr.push_back("".into());
assert_eq!(ptr.tokens().count(), 1);
ptr.pop_back();
assert_eq!(ptr.tokens().count(), 0);
}
{
let mut ptr = Pointer::root();
let input = ["", "", "", "foo", "", "bar", "baz", ""];
for (idx, s) in input.iter().enumerate() {
assert_eq!(ptr.tokens().count(), idx);
ptr.push_back(s.into());
}
assert_eq!(ptr.tokens().count(), input.len());
for (idx, s) in input.iter().enumerate() {
assert_eq!(ptr.tokens().count(), 8 - idx);
assert_eq!(ptr.front().unwrap().as_str(), *s);
assert_eq!(ptr.pop_front().unwrap().as_str(), *s);
}
assert_eq!(ptr.tokens().count(), 0);
assert!(ptr.front().is_none());
assert!(ptr.pop_front().is_none());
}
}

#[test]
fn test_formatting() {
assert_eq!(Pointer::new(["foo", "bar"]), "/foo/bar");
Expand Down

0 comments on commit 8335883

Please sign in to comment.