@@ -2,6 +2,75 @@ use fancy_regex::Regex;
22use serde:: { de:: Error , Deserialize , Deserializer } ;
33use std:: borrow:: Cow ;
44
5+ use path_slash:: PathBufExt ;
6+ use std:: path:: { PathBuf , Path } ;
7+
8+ #[ derive( Debug , Default , Clone ) ]
9+ pub struct Trie < T > {
10+ inner : radix_trie:: Trie < String , ( PathBuf , T ) > ,
11+ }
12+
13+ impl < T > Trie < T > {
14+ fn key < P : AsRef < Path > > ( & self , key : & P ) -> String {
15+ let mut p = normalize_path ( key. as_ref ( ) . to_string_lossy ( ) ) ;
16+
17+ if !p. ends_with ( '/' ) {
18+ p. push ( '/' ) ;
19+ }
20+
21+ p
22+ }
23+
24+ pub fn get_ancestor_value < P : AsRef < Path > > ( & self , key : & P ) -> Option < & T > {
25+ self . inner . get_ancestor_value ( & self . key ( & key) ) . map ( |t| & t. 1 )
26+ }
27+
28+ pub fn insert < P : AsRef < Path > > ( & mut self , key : P , value : T ) -> ( ) {
29+ let k = self . key ( & key) ;
30+ let p = PathBuf :: from ( k. clone ( ) ) ;
31+
32+ self . inner . insert ( k, ( p, value) ) . map ( |t| t. 1 ) ;
33+ }
34+ }
35+
36+ pub fn normalize_path < P : AsRef < str > > ( original : P ) -> String {
37+ let original_str = original. as_ref ( ) ;
38+
39+ let p = PathBuf :: from ( original_str) ;
40+ let mut str = clean_path:: clean ( p)
41+ . to_slash_lossy ( )
42+ . to_string ( ) ;
43+
44+ if original_str. ends_with ( '/' ) && !str. ends_with ( '/' ) {
45+ str. push ( '/' ) ;
46+ }
47+
48+ str
49+ }
50+
51+ #[ cfg( test) ]
52+ mod tests {
53+ use super :: * ;
54+
55+ #[ test]
56+ fn test_normalize_path ( ) {
57+ assert_eq ! ( normalize_path( "" ) , "." ) ;
58+ assert_eq ! ( normalize_path( "/" ) , "/" ) ;
59+ assert_eq ! ( normalize_path( "foo" ) , "foo" ) ;
60+ assert_eq ! ( normalize_path( "foo/bar" ) , "foo/bar" ) ;
61+ assert_eq ! ( normalize_path( "foo//bar" ) , "foo/bar" ) ;
62+ assert_eq ! ( normalize_path( "foo/./bar" ) , "foo/bar" ) ;
63+ assert_eq ! ( normalize_path( "foo/../bar" ) , "bar" ) ;
64+ assert_eq ! ( normalize_path( "foo/bar/.." ) , "foo" ) ;
65+ assert_eq ! ( normalize_path( "foo/../../bar" ) , "../bar" ) ;
66+ assert_eq ! ( normalize_path( "../foo/../../bar" ) , "../../bar" ) ;
67+ assert_eq ! ( normalize_path( "./foo" ) , "foo" ) ;
68+ assert_eq ! ( normalize_path( "../foo" ) , "../foo" ) ;
69+ assert_eq ! ( normalize_path( "/foo/bar" ) , "/foo/bar" ) ;
70+ assert_eq ! ( normalize_path( "/foo/bar/" ) , "/foo/bar/" ) ;
71+ }
72+ }
73+
574fn strip_slash_escape ( str : & str ) -> String {
675 let mut res = String :: default ( ) ;
776 res. reserve_exact ( str. len ( ) ) ;
0 commit comments