@@ -51,9 +51,39 @@ mod pkg {
51
51
#[ cfg( target_os = "windows" ) ]
52
52
mod path_transform {
53
53
use std:: collections:: HashMap ;
54
- use std:: path:: { Component , Path , PathBuf , Prefix } ;
54
+ use std:: path:: { Component , Components , Path , PathBuf , Prefix , PrefixComponent } ;
55
55
use std:: str;
56
56
57
+ fn take_prefix < ' a > ( components : & ' a mut Components ) -> PrefixComponent < ' a > {
58
+ let prefix = components. next ( ) . unwrap ( ) ;
59
+ let pc = match prefix {
60
+ Component :: Prefix ( pc) => pc,
61
+ _ => panic ! ( "unrecognised start to path: {:?}" , prefix) ,
62
+ } ;
63
+ let root = components. next ( ) . unwrap ( ) ;
64
+ if root != Component :: RootDir {
65
+ panic ! ( "unexpected non-root component in path starting {:?}" , prefix)
66
+ }
67
+ pc
68
+ }
69
+
70
+ fn transform_prefix_component ( pc : PrefixComponent ) -> Option < String > {
71
+ match pc. kind ( ) {
72
+ // Transforming these to the same place means these may flip-flop
73
+ // in the tracking map, but they're equivalent so not really an
74
+ // issue
75
+ Prefix :: Disk ( diskchar) |
76
+ Prefix :: VerbatimDisk ( diskchar) => {
77
+ assert ! ( diskchar. is_ascii_alphabetic( ) ) ;
78
+ Some ( format ! ( "/prefix/disk-{}" , str :: from_utf8( & [ diskchar] ) . unwrap( ) ) )
79
+ } ,
80
+ Prefix :: Verbatim ( _) |
81
+ Prefix :: VerbatimUNC ( _, _) |
82
+ Prefix :: DeviceNS ( _) |
83
+ Prefix :: UNC ( _, _) => None ,
84
+ }
85
+ }
86
+
57
87
pub struct PathTransformer {
58
88
dist_to_local_path : HashMap < String , PathBuf > ,
59
89
}
@@ -72,31 +102,8 @@ mod path_transform {
72
102
let mut components = p. components ( ) ;
73
103
74
104
let maybe_dist_prefix = if p. is_absolute ( ) {
75
- let prefix = components. next ( ) . unwrap ( ) ;
76
- let dist_prefix = match prefix {
77
- Component :: Prefix ( pc) => {
78
- match pc. kind ( ) {
79
- // Transforming these to the same place means these may flip-flop
80
- // in the tracking map, but they're equivalent so not really an
81
- // issue
82
- Prefix :: Disk ( diskchar) |
83
- Prefix :: VerbatimDisk ( diskchar) => {
84
- assert ! ( diskchar. is_ascii_alphabetic( ) ) ;
85
- format ! ( "disk-{}" , str :: from_utf8( & [ diskchar] ) . unwrap( ) )
86
- } ,
87
- Prefix :: Verbatim ( _) |
88
- Prefix :: VerbatimUNC ( _, _) |
89
- Prefix :: DeviceNS ( _) |
90
- Prefix :: UNC ( _, _) => return None ,
91
- }
92
- } ,
93
- _ => panic ! ( "unrecognised start to path {:?}" , p) ,
94
- } ;
95
-
96
- let root = components. next ( ) . unwrap ( ) ;
97
- if root != Component :: RootDir { panic ! ( "unexpected non-root component in {:?}" , p) }
98
-
99
- Some ( dist_prefix)
105
+ let pc = take_prefix ( & mut components) ;
106
+ Some ( transform_prefix_component ( pc) ?)
100
107
} else {
101
108
None
102
109
} ;
@@ -105,7 +112,13 @@ mod path_transform {
105
112
for component in components {
106
113
let part = match component {
107
114
Component :: Prefix ( _) |
108
- Component :: RootDir => panic ! ( "unexpected part in path {:?}" , p) ,
115
+ Component :: RootDir => {
116
+ // On Windows there is such a thing as a path like C:file.txt
117
+ // It's not clear to me what the semantics of such a path are,
118
+ // so give up.
119
+ error ! ( "unexpected part in path {:?}" , p) ;
120
+ return None
121
+ } ,
109
122
Component :: Normal ( osstr) => osstr. to_str ( ) ?,
110
123
// TODO: should be forbidden
111
124
Component :: CurDir => "." ,
@@ -117,14 +130,34 @@ mod path_transform {
117
130
dist_suffix. push_str ( part)
118
131
}
119
132
120
- let dist_path = if let Some ( dist_prefix) = maybe_dist_prefix {
121
- format ! ( "/prefix/{}/{}" , dist_prefix, dist_suffix)
133
+ let dist_path = if let Some ( mut dist_prefix) = maybe_dist_prefix {
134
+ dist_prefix. push ( '/' ) ;
135
+ dist_prefix. push_str ( & dist_suffix) ;
136
+ dist_prefix
122
137
} else {
123
138
dist_suffix
124
139
} ;
125
140
self . dist_to_local_path . insert ( dist_path. clone ( ) , p. to_owned ( ) ) ;
126
141
Some ( dist_path)
127
142
}
143
+ pub fn disk_mappings ( & self ) -> impl Iterator < Item =( PathBuf , String ) > {
144
+ let mut mappings = HashMap :: new ( ) ;
145
+ for ( _dist_path, local_path) in self . dist_to_local_path . iter ( ) {
146
+ if !local_path. is_absolute ( ) {
147
+ continue
148
+ }
149
+ let mut components = local_path. components ( ) ;
150
+ let local_prefix = take_prefix ( & mut components) ;
151
+ let local_prefix_component = Component :: Prefix ( local_prefix) ;
152
+ let local_prefix_path: & Path = local_prefix_component. as_ref ( ) ;
153
+ if mappings. contains_key ( local_prefix_path) {
154
+ continue
155
+ }
156
+ let dist_prefix = transform_prefix_component ( local_prefix) . unwrap ( ) ;
157
+ mappings. insert ( local_prefix_path. to_owned ( ) , dist_prefix) ;
158
+ }
159
+ mappings. into_iter ( )
160
+ }
128
161
pub fn to_local ( & self , p : & str ) -> PathBuf {
129
162
self . dist_to_local_path . get ( p) . unwrap ( ) . clone ( )
130
163
}
@@ -133,6 +166,7 @@ mod path_transform {
133
166
134
167
#[ cfg( unix) ]
135
168
mod path_transform {
169
+ use std:: iter;
136
170
use std:: path:: { Path , PathBuf } ;
137
171
138
172
pub struct PathTransformer ;
@@ -146,6 +180,9 @@ mod path_transform {
146
180
pub fn to_dist ( & mut self , p : & Path ) -> Option < String > {
147
181
p. as_os_str ( ) . to_str ( ) . map ( Into :: into)
148
182
}
183
+ pub fn disk_mappings ( & self ) -> impl Iterator < Item =( PathBuf , String ) > {
184
+ iter:: empty ( )
185
+ }
149
186
pub fn to_local ( & self , p : & str ) -> PathBuf {
150
187
PathBuf :: from ( p)
151
188
}
0 commit comments