1
1
use semver;
2
2
use std:: hash:: Hash ;
3
+ use std:: sync:: Arc ;
3
4
use std:: fmt:: { mod, Show , Formatter } ;
4
5
use std:: hash;
5
6
use serialize:: { Encodable , Encoder , Decodable , Decoder } ;
@@ -10,17 +11,23 @@ use util::{CargoResult, CargoError, short_hash, ToSemver};
10
11
use core:: source:: SourceId ;
11
12
12
13
/// Identifier for a specific version of a package in a specific source.
13
- #[ deriving( Clone , PartialEq , PartialOrd , Ord ) ]
14
+ #[ deriving( Clone ) ]
14
15
pub struct PackageId {
16
+ inner : Arc < PackageIdInner > ,
17
+ }
18
+
19
+ #[ deriving( PartialEq , PartialOrd , Eq , Ord ) ]
20
+ struct PackageIdInner {
15
21
name : String ,
16
22
version : semver:: Version ,
17
23
source_id : SourceId ,
18
24
}
19
25
20
26
impl < E , S : Encoder < E > > Encodable < S , E > for PackageId {
21
27
fn encode ( & self , s : & mut S ) -> Result < ( ) , E > {
22
- let source = self . source_id . to_url ( ) ;
23
- let encoded = format ! ( "{} {} ({})" , self . name, self . version, source) ;
28
+ let source = self . inner . source_id . to_url ( ) ;
29
+ let encoded = format ! ( "{} {} ({})" , self . inner. name, self . inner. version,
30
+ source) ;
24
31
encoded. encode ( s)
25
32
}
26
33
}
@@ -36,22 +43,39 @@ impl<E, D: Decoder<E>> Decodable<D, E> for PackageId {
36
43
let source_id = SourceId :: from_url ( captures. at ( 3 ) . to_string ( ) ) ;
37
44
38
45
Ok ( PackageId {
39
- name : name. to_string ( ) ,
40
- version : version,
41
- source_id : source_id
46
+ inner : Arc :: new ( PackageIdInner {
47
+ name : name. to_string ( ) ,
48
+ version : version,
49
+ source_id : source_id,
50
+ } ) ,
42
51
} )
43
52
}
44
53
}
45
54
46
55
impl < S : hash:: Writer > Hash < S > for PackageId {
47
56
fn hash ( & self , state : & mut S ) {
48
- self . name . hash ( state) ;
49
- self . version . to_string ( ) . hash ( state) ;
50
- self . source_id . hash ( state) ;
57
+ self . inner . name . hash ( state) ;
58
+ self . inner . version . to_string ( ) . hash ( state) ;
59
+ self . inner . source_id . hash ( state) ;
51
60
}
52
61
}
53
62
63
+ impl PartialEq for PackageId {
64
+ fn eq ( & self , other : & PackageId ) -> bool {
65
+ self . inner . eq ( & * other. inner )
66
+ }
67
+ }
68
+ impl PartialOrd for PackageId {
69
+ fn partial_cmp ( & self , other : & PackageId ) -> Option < Ordering > {
70
+ self . inner . partial_cmp ( & * other. inner )
71
+ }
72
+ }
54
73
impl Eq for PackageId { }
74
+ impl Ord for PackageId {
75
+ fn cmp ( & self , other : & PackageId ) -> Ordering {
76
+ self . inner . cmp ( & * other. inner )
77
+ }
78
+ }
55
79
56
80
#[ deriving( Clone , Show , PartialEq ) ]
57
81
pub enum PackageIdError {
@@ -80,27 +104,30 @@ impl PackageId {
80
104
sid : & SourceId ) -> CargoResult < PackageId > {
81
105
let v = try!( version. to_semver ( ) . map_err ( InvalidVersion ) ) ;
82
106
Ok ( PackageId {
83
- name : name. to_string ( ) ,
84
- version : v,
85
- source_id : sid. clone ( )
107
+ inner : Arc :: new ( PackageIdInner {
108
+ name : name. to_string ( ) ,
109
+ version : v,
110
+ source_id : sid. clone ( ) ,
111
+ } ) ,
86
112
} )
87
113
}
88
114
89
115
pub fn get_name ( & self ) -> & str {
90
- self . name . as_slice ( )
116
+ self . inner . name . as_slice ( )
91
117
}
92
118
93
119
pub fn get_version ( & self ) -> & semver:: Version {
94
- & self . version
120
+ & self . inner . version
95
121
}
96
122
97
123
pub fn get_source_id ( & self ) -> & SourceId {
98
- & self . source_id
124
+ & self . inner . source_id
99
125
}
100
126
101
127
pub fn generate_metadata ( & self ) -> Metadata {
102
128
let metadata = short_hash (
103
- & ( self . name . as_slice ( ) , self . version . to_string ( ) , & self . source_id ) ) ;
129
+ & ( self . inner . name . as_slice ( ) , self . inner . version . to_string ( ) ,
130
+ & self . inner . source_id ) ) ;
104
131
let extra_filename = format ! ( "-{}" , metadata) ;
105
132
106
133
Metadata { metadata : metadata, extra_filename : extra_filename }
@@ -119,10 +146,10 @@ static CENTRAL_REPO: &'static str = "http://rust-lang.org/central-repo";
119
146
120
147
impl Show for PackageId {
121
148
fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
122
- try!( write ! ( f, "{} v{}" , self . name, self . version) ) ;
149
+ try!( write ! ( f, "{} v{}" , self . inner . name, self . inner . version) ) ;
123
150
124
- if self . source_id . to_string ( ) . as_slice ( ) != CENTRAL_REPO {
125
- try!( write ! ( f, " ({})" , self . source_id) ) ;
151
+ if self . inner . source_id . to_string ( ) . as_slice ( ) != CENTRAL_REPO {
152
+ try!( write ! ( f, " ({})" , self . inner . source_id) ) ;
126
153
}
127
154
128
155
Ok ( ( ) )
0 commit comments