@@ -384,7 +384,258 @@ impl<T: fmt::Debug> Node<T> {
384384
385385 pub fn find ( & self , bytes : & [ u8 ] ) -> Option < ( & T , SmallVec < [ Range < usize > ; 8 ] > ) > {
386386 let mut ranges = SmallVec :: < [ Range < usize > ; 8 ] > :: new ( ) ; // opt!
387- return self . _find ( 0 , bytes, & mut ranges) . map ( |t| ( t, ranges) ) ;
387+ self . _find ( 0 , bytes, & mut ranges) . map ( |t| ( t, ranges) )
388+ }
389+
390+ pub fn _remove ( & mut self , mut start : usize , mut bytes : & [ u8 ] ) -> Option < T > {
391+ let mut m = bytes. len ( ) ;
392+ match & self . key {
393+ Key :: String ( s) => {
394+ let n = s. len ( ) ;
395+ let mut flag = m >= n;
396+
397+ // opt!
398+ if flag {
399+ if n == 1 {
400+ flag = s[ 0 ] == bytes[ 0 ] ;
401+ } else {
402+ flag = s == & bytes[ ..n] ;
403+ }
404+ }
405+
406+ // starts with prefix
407+ if flag {
408+ m -= n;
409+ start += n;
410+ bytes = & bytes[ n..] ;
411+
412+ if m == 0 {
413+ return self . value . take ( ) ;
414+ } else {
415+ // static
416+ if let Some ( id) = self . nodes0 . as_mut ( ) . and_then ( |nodes| {
417+ nodes
418+ . binary_search_by ( |node| match & node. key {
419+ Key :: String ( s) => {
420+ // s[0].cmp(&bytes[0])
421+ // opt!
422+ // lets `/` at end
423+ compare ( s[ 0 ] , bytes[ 0 ] )
424+ }
425+ Key :: Parameter ( _) => unreachable ! ( ) ,
426+ } )
427+ . ok ( )
428+ . and_then ( |i| nodes[ i] . _remove ( start, bytes) )
429+ } ) {
430+ return Some ( id) ;
431+ }
432+ }
433+
434+ // parameter
435+ if let Some ( id) = self . nodes1 . as_mut ( ) . and_then ( |nodes| {
436+ let b = m > 0 ;
437+ nodes
438+ . iter_mut ( )
439+ . filter ( |node| match node. key {
440+ Key :: Parameter ( pk)
441+ if pk == Kind :: Normal || pk == Kind :: OneOrMore =>
442+ {
443+ b
444+ }
445+ _ => true ,
446+ } )
447+ . find_map ( |node| node. _remove ( start, bytes) )
448+ } ) {
449+ return Some ( id) ;
450+ }
451+ } else if n == 1 && s[ 0 ] == b'/' {
452+ if let Some ( id) = self . nodes1 . as_mut ( ) . and_then ( |nodes| {
453+ nodes
454+ . iter_mut ( )
455+ . filter ( |node| {
456+ matches ! ( node. key,
457+ Key :: Parameter ( pk)
458+ if pk == Kind :: OptionalSegment
459+ || pk == Kind :: ZeroOrMoreSegment
460+ )
461+ } )
462+ . find_map ( |node| node. _remove ( start, bytes) )
463+ } ) {
464+ return Some ( id) ;
465+ }
466+ }
467+ }
468+ Key :: Parameter ( k) => match k {
469+ Kind :: Normal | Kind :: Optional | Kind :: OptionalSegment => {
470+ if m == 0 {
471+ if k == & Kind :: Normal {
472+ return None ;
473+ }
474+
475+ // last
476+ if self . nodes0 . is_none ( ) && self . nodes1 . is_none ( ) {
477+ return self . value . take ( ) ;
478+ }
479+ } else {
480+ // static
481+ if let Some ( id) = self . nodes0 . as_mut ( ) . and_then ( |nodes| {
482+ nodes. iter_mut ( ) . find_map ( |node| match & node. key {
483+ Key :: String ( s) => {
484+ let mut keep_running = true ;
485+ if let Some ( n) = bytes
486+ . iter ( )
487+ // as it turns out doing .copied() here is much slower than dereferencing in the closure
488+ // https://godbolt.org/z/7dnW91T1Y
489+ . take_while ( |b| {
490+ if keep_running && * * b == b'/' {
491+ keep_running = false ;
492+ true
493+ } else {
494+ keep_running
495+ }
496+ } )
497+ . enumerate ( )
498+ . find_map ( |( n, b) | ( s[ 0 ] == * b) . then_some ( n) )
499+ {
500+ node. _remove ( start + n, & bytes[ n..] )
501+ } else {
502+ None
503+ }
504+ }
505+ Key :: Parameter ( _) => unreachable ! ( ) ,
506+ } )
507+ } ) {
508+ return Some ( id) ;
509+ }
510+
511+ // parameter => `:a:b:c`
512+ if let Some ( id) = self . nodes1 . as_mut ( ) . and_then ( |nodes| {
513+ let b = m - 1 > 0 ;
514+ nodes
515+ . iter_mut ( )
516+ . filter ( |node| match node. key {
517+ Key :: Parameter ( pk)
518+ if pk == Kind :: Normal || pk == Kind :: OneOrMore =>
519+ {
520+ b
521+ }
522+ _ => true ,
523+ } )
524+ . find_map ( |node| node. _remove ( start + 1 , & bytes[ 1 ..] ) )
525+ } ) {
526+ return Some ( id) ;
527+ }
528+ }
529+
530+ // parameter => `:a:b?:c?`
531+ if k == & Kind :: Optional || k == & Kind :: OptionalSegment {
532+ if let Some ( id) = self . nodes1 . as_mut ( ) . and_then ( |nodes| {
533+ let b = m > 0 ;
534+ nodes
535+ . iter_mut ( )
536+ . filter ( |node| match & node. key {
537+ Key :: Parameter ( pk)
538+ if pk == & Kind :: Normal || pk == & Kind :: OneOrMore =>
539+ {
540+ b
541+ }
542+ _ => true ,
543+ } )
544+ . find_map ( |node| node. _remove ( start, bytes) )
545+ } ) {
546+ // param should be empty
547+ return Some ( id) ;
548+ }
549+ }
550+
551+ if let Some ( n) = bytes. iter ( ) . position ( |b| * b == b'/' ) {
552+ bytes = & bytes[ n..] ;
553+ } else {
554+ if self . value . is_some ( ) {
555+ return self . value . take ( ) ;
556+ }
557+ bytes = & bytes[ m..] ;
558+ }
559+
560+ if k == & Kind :: OptionalSegment {
561+ if let Some ( id) = self . nodes0 . as_mut ( ) . and_then ( |nodes| {
562+ nodes
563+ . last_mut ( )
564+ . filter ( |node| match & node. key {
565+ Key :: String ( s) => s[ 0 ] == b'/' ,
566+ Key :: Parameter ( _) => unreachable ! ( ) ,
567+ } )
568+ . and_then ( |node| node. _remove ( start, bytes) )
569+ } ) {
570+ return Some ( id) ;
571+ }
572+ }
573+ }
574+ Kind :: OneOrMore | Kind :: ZeroOrMore | Kind :: ZeroOrMoreSegment => {
575+ let is_one_or_more = k == & Kind :: OneOrMore ;
576+ if m == 0 {
577+ if is_one_or_more {
578+ return None ;
579+ }
580+
581+ if self . nodes0 . is_none ( ) && self . nodes1 . is_none ( ) {
582+ return self . value . take ( ) ;
583+ }
584+ } else {
585+ if self . nodes0 . is_none ( ) && self . nodes1 . is_none ( ) {
586+ if self . value . is_some ( ) {
587+ return self . value . take ( ) ;
588+ }
589+ }
590+
591+ // static
592+ if let Some ( id) = self . nodes0 . as_mut ( ) . and_then ( |nodes| {
593+ nodes. iter_mut ( ) . find_map ( |node| {
594+ if let Key :: String ( s) = & node. key {
595+ let right_length = if is_one_or_more {
596+ m > s. len ( )
597+ } else {
598+ m >= s. len ( )
599+ } ;
600+ if right_length {
601+ return if let Some ( n) = bytes
602+ . iter ( )
603+ . enumerate ( )
604+ . find_map ( |( n, b) | ( s[ 0 ] == * b) . then_some ( n) )
605+ {
606+ node. _remove ( start + n, & bytes[ n..] )
607+ } else {
608+ None
609+ } ;
610+ }
611+ }
612+ None
613+ } )
614+ } ) {
615+ return Some ( id) ;
616+ }
617+ }
618+
619+ if k == & Kind :: ZeroOrMoreSegment {
620+ return self . nodes0 . as_mut ( ) . and_then ( |nodes| {
621+ nodes
622+ . iter_mut ( )
623+ . last ( )
624+ . filter ( |node| match & node. key {
625+ Key :: String ( s) => s[ 0 ] == b'/' ,
626+ Key :: Parameter ( _) => unreachable ! ( ) ,
627+ } )
628+ . and_then ( |node| node. _remove ( start, bytes) )
629+ } ) ;
630+ }
631+ }
632+ } ,
633+ }
634+ None
635+ }
636+
637+ pub fn remove ( & mut self , bytes : & [ u8 ] ) -> Option < T > {
638+ self . _remove ( 0 , bytes)
388639 }
389640}
390641
0 commit comments