@@ -280,12 +280,26 @@ impl Pointer {
280
280
. map ( |s| unsafe { Self :: new_unchecked ( s) } )
281
281
}
282
282
283
- /// Attempts to get a `Token` or a segment of the `Pointer`, depending on
284
- /// the type of index.
283
+ /// Returns whether `self` has a suffix of `other`.
285
284
///
286
- /// Returns `None` if the index is out of bounds.
285
+ /// Note that `Pointer::root` is only a valid suffix of itself.
286
+ pub fn ends_with ( & self , other : & Self ) -> bool {
287
+ ( self . is_root ( ) && other. is_root ( ) )
288
+ || ( !other. is_root ( ) && self . as_str ( ) . ends_with ( & other. 0 ) )
289
+ }
290
+
291
+ /// Returns whether `self` has a prefix of `other.`
287
292
///
288
- /// Note that this operation is O(n).
293
+ /// Note that `Pointer::root` is a valid prefix of any `Pointer` (including
294
+ /// itself).
295
+ pub fn starts_with ( & self , other : & Self ) -> bool {
296
+ self . as_str ( ) . starts_with ( & other. 0 )
297
+ // ensure we end at a token boundary
298
+ && ( other. len ( ) == self . len ( ) || self . 0 . as_bytes ( ) [ other. len ( ) ] == b'/' )
299
+ }
300
+
301
+ /// Attempts to get a `Token` by the index. Returns `None` if the index is
302
+ /// out of bounds.
289
303
///
290
304
/// ## Example
291
305
/// ```rust
@@ -1372,6 +1386,58 @@ mod tests {
1372
1386
assert_eq ! ( stripped, "/to/some/value" ) ;
1373
1387
}
1374
1388
1389
+ #[ test]
1390
+ fn ends_with ( ) {
1391
+ // positive cases
1392
+ let p = Pointer :: from_static ( "/foo/bar" ) ;
1393
+ let q = Pointer :: from_static ( "/bar" ) ;
1394
+ assert ! ( p. ends_with( q) ) ;
1395
+ let q = Pointer :: from_static ( "/foo/bar" ) ;
1396
+ assert ! ( p. ends_with( q) ) ;
1397
+
1398
+ // negative cases
1399
+ let q = Pointer :: from_static ( "/barz" ) ;
1400
+ assert ! ( !p. ends_with( q) ) ;
1401
+ let q = Pointer :: from_static ( "/" ) ;
1402
+ assert ! ( !p. ends_with( q) ) ;
1403
+ let q = Pointer :: from_static ( "" ) ;
1404
+ assert ! ( !p. ends_with( q) ) ;
1405
+ let q = Pointer :: from_static ( "/qux/foo/bar" ) ;
1406
+ assert ! ( !p. ends_with( q) ) ;
1407
+
1408
+ // edge case - both root
1409
+ let p = Pointer :: root ( ) ;
1410
+ let q = Pointer :: root ( ) ;
1411
+ assert ! ( p. ends_with( q) ) ;
1412
+ }
1413
+
1414
+ #[ test]
1415
+ fn starts_with ( ) {
1416
+ // positive cases
1417
+ let p = Pointer :: from_static ( "/foo/bar" ) ;
1418
+ let q = Pointer :: from_static ( "/foo" ) ;
1419
+ assert ! ( p. starts_with( q) ) ;
1420
+ let q = Pointer :: from_static ( "/foo/bar" ) ;
1421
+ assert ! ( p. starts_with( q) ) ;
1422
+
1423
+ // negative cases
1424
+ let q = Pointer :: from_static ( "/" ) ;
1425
+ assert ! ( !p. starts_with( q) ) ;
1426
+ let q = Pointer :: from_static ( "/fo" ) ;
1427
+ assert ! ( !p. starts_with( q) ) ;
1428
+ let q = Pointer :: from_static ( "/foo/" ) ;
1429
+ assert ! ( !p. starts_with( q) ) ;
1430
+
1431
+ // edge cases: other is root
1432
+ let p = Pointer :: root ( ) ;
1433
+ let q = Pointer :: root ( ) ;
1434
+ assert ! ( p. starts_with( q) ) ;
1435
+ let p = Pointer :: from_static ( "/" ) ;
1436
+ assert ! ( p. starts_with( q) ) ;
1437
+ let p = Pointer :: from_static ( "/any/thing" ) ;
1438
+ assert ! ( p. starts_with( q) ) ;
1439
+ }
1440
+
1375
1441
#[ test]
1376
1442
fn parse_error_is_no_leading_backslash ( ) {
1377
1443
let err = ParseError :: NoLeadingBackslash ;
0 commit comments