@@ -403,10 +403,17 @@ pub struct Dependency {
403
403
optional : bool ,
404
404
}
405
405
406
+ /// Entry with data that corresponds to [`tar::EntryType`].
407
+ #[ non_exhaustive]
408
+ enum EntryData {
409
+ Regular ( String ) ,
410
+ Symlink ( PathBuf ) ,
411
+ }
412
+
406
413
/// A file to be created in a package.
407
414
struct PackageFile {
408
415
path : String ,
409
- contents : String ,
416
+ contents : EntryData ,
410
417
/// The Unix mode for the file. Note that when extracted on Windows, this
411
418
/// is mostly ignored since it doesn't have the same style of permissions.
412
419
mode : u32 ,
@@ -780,13 +787,24 @@ impl Package {
780
787
pub fn file_with_mode ( & mut self , path : & str , mode : u32 , contents : & str ) -> & mut Package {
781
788
self . files . push ( PackageFile {
782
789
path : path. to_string ( ) ,
783
- contents : contents. to_string ( ) ,
790
+ contents : EntryData :: Regular ( contents. into ( ) ) ,
784
791
mode,
785
792
extra : false ,
786
793
} ) ;
787
794
self
788
795
}
789
796
797
+ /// Adds a symlink to a path to the package.
798
+ pub fn symlink ( & mut self , dst : & str , src : & str ) -> & mut Package {
799
+ self . files . push ( PackageFile {
800
+ path : dst. to_string ( ) ,
801
+ contents : EntryData :: Symlink ( src. into ( ) ) ,
802
+ mode : DEFAULT_MODE ,
803
+ extra : false ,
804
+ } ) ;
805
+ self
806
+ }
807
+
790
808
/// Adds an "extra" file that is not rooted within the package.
791
809
///
792
810
/// Normal files are automatically placed within a directory named
@@ -795,7 +813,7 @@ impl Package {
795
813
pub fn extra_file ( & mut self , path : & str , contents : & str ) -> & mut Package {
796
814
self . files . push ( PackageFile {
797
815
path : path. to_string ( ) ,
798
- contents : contents. to_string ( ) ,
816
+ contents : EntryData :: Regular ( contents. to_string ( ) ) ,
799
817
mode : DEFAULT_MODE ,
800
818
extra : true ,
801
819
} ) ;
@@ -1033,7 +1051,7 @@ impl Package {
1033
1051
self . append_manifest ( & mut a) ;
1034
1052
}
1035
1053
if self . files . is_empty ( ) {
1036
- self . append ( & mut a, "src/lib.rs" , DEFAULT_MODE , "" ) ;
1054
+ self . append ( & mut a, "src/lib.rs" , DEFAULT_MODE , & EntryData :: Regular ( "" . into ( ) ) ) ;
1037
1055
} else {
1038
1056
for PackageFile {
1039
1057
path,
@@ -1107,10 +1125,10 @@ impl Package {
1107
1125
manifest. push_str ( "[lib]\n proc-macro = true\n " ) ;
1108
1126
}
1109
1127
1110
- self . append ( ar, "Cargo.toml" , DEFAULT_MODE , & manifest) ;
1128
+ self . append ( ar, "Cargo.toml" , DEFAULT_MODE , & EntryData :: Regular ( manifest. into ( ) ) ) ;
1111
1129
}
1112
1130
1113
- fn append < W : Write > ( & self , ar : & mut Builder < W > , file : & str , mode : u32 , contents : & str ) {
1131
+ fn append < W : Write > ( & self , ar : & mut Builder < W > , file : & str , mode : u32 , contents : & EntryData ) {
1114
1132
self . append_raw (
1115
1133
ar,
1116
1134
& format ! ( "{}-{}/{}" , self . name, self . vers, file) ,
@@ -1119,8 +1137,16 @@ impl Package {
1119
1137
) ;
1120
1138
}
1121
1139
1122
- fn append_raw < W : Write > ( & self , ar : & mut Builder < W > , path : & str , mode : u32 , contents : & str ) {
1140
+ fn append_raw < W : Write > ( & self , ar : & mut Builder < W > , path : & str , mode : u32 , contents : & EntryData ) {
1123
1141
let mut header = Header :: new_ustar ( ) ;
1142
+ let contents = match contents {
1143
+ EntryData :: Regular ( contents) => contents. as_str ( ) ,
1144
+ EntryData :: Symlink ( src) => {
1145
+ header. set_entry_type ( tar:: EntryType :: Symlink ) ;
1146
+ t ! ( header. set_link_name( src) ) ;
1147
+ "" // Symlink has no contents.
1148
+ }
1149
+ } ;
1124
1150
header. set_size ( contents. len ( ) as u64 ) ;
1125
1151
t ! ( header. set_path( path) ) ;
1126
1152
header. set_mode ( mode) ;
0 commit comments