1414use serde:: { Deserialize , Serialize } ;
1515use std:: collections:: BTreeMap ;
1616
17+ use crate :: handlers:: publish:: PartialPackageDep ;
18+
1719#[ derive( Serialize , Deserialize ) ]
1820pub struct IndexFile {
1921 /// Each published instance for this specific package, keyed by their
2022 /// versions. The reason we are doing this type of mapping is for use of
21- /// ease, we are effectively duplicating version of package but keeping
22- /// `PackageEntry` self contained.
23+ /// ease and deterministic ordering , we are effectively duplicating version
24+ /// of package but keeping `PackageEntry` self contained.
2325 #[ serde( flatten) ]
2426 versions : BTreeMap < semver:: Version , PackageEntry > ,
2527}
@@ -35,7 +37,7 @@ pub struct IndexFile {
3537/// 5. Dependencies of this package. If there are other packages this package
3638/// depends on, some information can be directly found in the root package
3739/// to enable parallel fetching.
38- #[ derive( Serialize , Deserialize ) ]
40+ #[ derive( Serialize , Deserialize , Clone ) ]
3941pub struct PackageEntry {
4042 /// Name of the package.
4143 /// This is the actual package name needed in forc.toml file to fetch this
@@ -56,7 +58,46 @@ pub struct PackageEntry {
5658 abi_cid : Option < String > ,
5759 /// Dependencies of the current package entry. Can be consumed to enable
5860 /// parallel fetching by the consumers of this index, mainly forc.
59- dependencies : Vec < Box < PackageEntry > > ,
61+ dependencies : Vec < PackageDependencyIdentifier > ,
62+ }
63+
64+ #[ derive( Serialize , Deserialize , Clone ) ]
65+ pub struct PackageDependencyIdentifier {
66+ /// Name of the dependency.
67+ /// Name and version information can be used by consumer of this index
68+ /// to resolve dependencies.
69+ package_name : String ,
70+ /// Version of the dependency.
71+ /// Name and version information can be used by consumer of this index
72+ /// to resolve dependencies.
73+ version : String ,
74+ }
75+
76+ impl PackageEntry {
77+ pub fn new (
78+ package_name : String ,
79+ version : semver:: Version ,
80+ source_cid : String ,
81+ abi_cid : Option < String > ,
82+ dependencies : Vec < PackageDependencyIdentifier > ,
83+ ) -> Self {
84+ Self {
85+ package_name,
86+ version,
87+ source_cid,
88+ abi_cid,
89+ dependencies,
90+ }
91+ }
92+ }
93+
94+ impl From < PartialPackageDep > for PackageDependencyIdentifier {
95+ fn from ( value : PartialPackageDep ) -> Self {
96+ Self {
97+ package_name : value. dependency_package_name ,
98+ version : value. dependency_version_req ,
99+ }
100+ }
60101}
61102
62103#[ cfg( test) ]
@@ -108,47 +149,39 @@ mod tests {
108149 let v011 = & deserialized. versions [ & semver:: Version :: new ( 0 , 11 , 0 ) ] ;
109150 assert_eq ! ( v011. source_cid, "QmOlderHash" ) ;
110151 assert_eq ! ( v011. abi_cid, Some ( "QmOlderAbiHash" . to_string( ) ) ) ;
152+ assert_eq ! ( v011. dependencies. len( ) , 0 ) ;
111153
112154 let v012 = & deserialized. versions [ & semver:: Version :: new ( 0 , 12 , 0 ) ] ;
113155 assert_eq ! ( v012. source_cid, "QmExampleHash" ) ;
114156 assert_eq ! ( v012. abi_cid, Some ( "QmExampleAbiHash" . to_string( ) ) ) ;
157+ assert_eq ! ( v012. dependencies. len( ) , 0 ) ;
115158 }
116159
117160 #[ test]
118161 fn test_json_with_dependencies ( ) {
119- // Test parsing a JSON with nested dependencies
162+ // Test parsing a JSON with dependencies
120163 let json = r#"{
121- "1.0.0": {
122- "package_name": "main-package",
123- "version": "1.0.0",
124- "source_cid": "QmMainHash",
125- "abi_cid": null,
126- "dependencies": [
127- {
128- "package_name": "dep-package",
129- "version": "0.5.0",
130- "source_cid": "QmDepHash",
131- "abi_cid": "QmDepAbiHash",
132- "dependencies": []
133- },
134- {
135- "package_name": "another-dep",
136- "version": "0.9.1",
137- "source_cid": "QmAnotherDepHash",
138- "abi_cid": null,
139- "dependencies": [
140- {
141- "package_name": "nested-dep",
142- "version": "0.2.0",
143- "source_cid": "QmNestedHash",
144- "abi_cid": "QmNestedAbiHash",
145- "dependencies": []
146- }
147- ]
148- }
149- ]
150- }
151- }"# ;
164+ "1.0.0": {
165+ "package_name": "main-package",
166+ "version": "1.0.0",
167+ "source_cid": "QmMainHash",
168+ "abi_cid": null,
169+ "dependencies": [
170+ {
171+ "package_name": "dep-package",
172+ "version": "^0.5.0"
173+ },
174+ {
175+ "package_name": "another-dep",
176+ "version": "=0.9.1"
177+ },
178+ {
179+ "package_name": "third-dep",
180+ "version": "0.2.0"
181+ }
182+ ]
183+ }
184+ }"# ;
152185
153186 let deserialized: IndexFile = serde_json:: from_str ( json) . unwrap ( ) ;
154187
@@ -163,44 +196,35 @@ mod tests {
163196 assert_eq ! ( main_pkg. source_cid, "QmMainHash" ) ;
164197 assert_eq ! ( main_pkg. abi_cid, None ) ;
165198
166- // Verify first-level dependencies
167- assert_eq ! ( main_pkg. dependencies. len( ) , 2 ) ;
199+ // Verify dependencies
200+ assert_eq ! ( main_pkg. dependencies. len( ) , 3 ) ;
168201
169202 // Check first dependency
170203 let dep1 = & main_pkg. dependencies [ 0 ] ;
171204 assert_eq ! ( dep1. package_name, "dep-package" ) ;
172- assert_eq ! ( dep1. version, semver:: Version :: new( 0 , 5 , 0 ) ) ;
173- assert_eq ! ( dep1. source_cid, "QmDepHash" ) ;
174- assert_eq ! ( dep1. abi_cid, Some ( "QmDepAbiHash" . to_string( ) ) ) ;
175- assert_eq ! ( dep1. dependencies. len( ) , 0 ) ;
205+ assert_eq ! ( dep1. version, "^0.5.0" ) ;
176206
177207 // Check second dependency
178208 let dep2 = & main_pkg. dependencies [ 1 ] ;
179209 assert_eq ! ( dep2. package_name, "another-dep" ) ;
180- assert_eq ! ( dep2. version, semver:: Version :: new( 0 , 9 , 1 ) ) ;
181- assert_eq ! ( dep2. source_cid, "QmAnotherDepHash" ) ;
182- assert_eq ! ( dep2. abi_cid, None ) ;
183-
184- // Verify nested dependency
185- assert_eq ! ( dep2. dependencies. len( ) , 1 ) ;
186- let nested_dep = & dep2. dependencies [ 0 ] ;
187- assert_eq ! ( nested_dep. package_name, "nested-dep" ) ;
188- assert_eq ! ( nested_dep. version, semver:: Version :: new( 0 , 2 , 0 ) ) ;
189- assert_eq ! ( nested_dep. source_cid, "QmNestedHash" ) ;
190- assert_eq ! ( nested_dep. abi_cid, Some ( "QmNestedAbiHash" . to_string( ) ) ) ;
191- assert_eq ! ( nested_dep. dependencies. len( ) , 0 ) ;
210+ assert_eq ! ( dep2. version, "=0.9.1" ) ;
211+
212+ // Check third dependency
213+ let dep3 = & main_pkg. dependencies [ 2 ] ;
214+ assert_eq ! ( dep3. package_name, "third-dep" ) ;
215+ assert_eq ! ( dep3. version, "0.2.0" ) ;
192216
193217 // Test round-trip serialization
194218 let serialized = serde_json:: to_string_pretty ( & deserialized) . unwrap ( ) ;
219+ println ! ( "Re-serialized JSON: {}" , serialized) ;
195220
196221 // Deserialize again to ensure it's valid
197222 let re_deserialized: IndexFile = serde_json:: from_str ( & serialized) . unwrap ( ) ;
198223 assert_eq ! ( re_deserialized. versions. len( ) , 1 ) ;
199224
200225 // Verify the structure is preserved
201226 let main_pkg2 = & re_deserialized. versions [ & semver:: Version :: new ( 1 , 0 , 0 ) ] ;
202- assert_eq ! ( main_pkg2. dependencies. len( ) , 2 ) ;
203- assert_eq ! ( main_pkg2. dependencies[ 1 ] . dependencies. len( ) , 1 ) ;
227+ assert_eq ! ( main_pkg2. dependencies. len( ) , 3 ) ;
204228 }
205229
206230 #[ test]
@@ -222,5 +246,31 @@ mod tests {
222246 assert_eq ! ( pkg. package_name, "minimal-package" ) ;
223247 assert_eq ! ( pkg. source_cid, "QmMinimalHash" ) ;
224248 assert_eq ! ( pkg. abi_cid, None ) ;
249+ assert_eq ! ( pkg. dependencies. len( ) , 0 ) ;
250+ }
251+
252+ #[ test]
253+ fn test_package_entry_new ( ) {
254+ // Test the new() constructor method
255+ let dependencies = vec ! [ PackageDependencyIdentifier {
256+ package_name: "dep1" . to_string( ) ,
257+ version: "^1.0" . to_string( ) ,
258+ } ] ;
259+
260+ let entry = PackageEntry :: new (
261+ "test-package" . to_string ( ) ,
262+ semver:: Version :: new ( 2 , 0 , 0 ) ,
263+ "QmTestHash" . to_string ( ) ,
264+ Some ( "QmAbiHash" . to_string ( ) ) ,
265+ dependencies. clone ( ) ,
266+ ) ;
267+
268+ assert_eq ! ( entry. package_name, "test-package" ) ;
269+ assert_eq ! ( entry. version, semver:: Version :: new( 2 , 0 , 0 ) ) ;
270+ assert_eq ! ( entry. source_cid, "QmTestHash" ) ;
271+ assert_eq ! ( entry. abi_cid, Some ( "QmAbiHash" . to_string( ) ) ) ;
272+ assert_eq ! ( entry. dependencies. len( ) , 1 ) ;
273+ assert_eq ! ( entry. dependencies[ 0 ] . package_name, "dep1" ) ;
274+ assert_eq ! ( entry. dependencies[ 0 ] . version, "^1.0" ) ;
225275 }
226276}
0 commit comments