11use std:: {
2- collections:: BTreeMap ,
32 fmt:: Formatter ,
43 str:: FromStr ,
54} ;
65
7- use common:: {
8- obj,
9- types:: ObjectKey ,
10- } ;
6+ use common:: types:: ObjectKey ;
117use errors:: ErrorMetadata ;
128use humansize:: {
139 FormatSize ,
1410 BINARY ,
1511} ;
12+ use serde:: {
13+ Deserialize ,
14+ Serialize ,
15+ } ;
16+ use serde_bytes:: ByteBuf ;
1617use value:: {
18+ codegen_convex_serialization,
1719 heap_size:: HeapSize ,
1820 id_v6:: DeveloperDocumentId ,
1921 sha256:: Sha256Digest ,
20- ConvexObject ,
2122 ConvexValue ,
2223} ;
2324
@@ -67,7 +68,15 @@ pub struct SourcePackage {
6768#[ cfg_attr( any( test, feature = "testing" ) , derive( proptest_derive:: Arbitrary ) ) ]
6869#[ derive( Copy , Clone , Debug , Eq , PartialEq , Default ) ]
6970pub struct PackageSize {
71+ #[ cfg_attr(
72+ any( test, feature = "testing" ) ,
73+ proptest( strategy = "0..=i64::MAX as usize" )
74+ ) ]
7075 pub zipped_size_bytes : usize ,
76+ #[ cfg_attr(
77+ any( test, feature = "testing" ) ,
78+ proptest( strategy = "0..=i64::MAX as usize" )
79+ ) ]
7180 pub unzipped_size_bytes : usize ,
7281}
7382
@@ -128,38 +137,39 @@ impl PackageSize {
128137 }
129138}
130139
131- impl TryFrom < ConvexObject > for PackageSize {
132- type Error = anyhow:: Error ;
140+ #[ derive( Serialize , Deserialize ) ]
141+ #[ serde( rename_all = "camelCase" ) ]
142+ pub struct SerializedPackageSize {
143+ zipped_size_bytes : i64 ,
144+ unzipped_size_bytes : i64 ,
145+ }
133146
134- fn try_from ( value : ConvexObject ) -> Result < Self , Self :: Error > {
135- let mut fields = BTreeMap :: from ( value ) ;
147+ impl TryFrom < SerializedPackageSize > for PackageSize {
148+ type Error = anyhow :: Error ;
136149
137- let zipped_size_bytes: usize = match fields. remove ( "zippedSizeBytes" ) {
138- Some ( ConvexValue :: Int64 ( i) ) => i as usize ,
139- _ => anyhow:: bail!( "Missing or invalid 'zippedSize' in {fields:?}" ) ,
140- } ;
141- let unzipped_size_bytes: usize = match fields. remove ( "unzippedSizeBytes" ) {
142- Some ( ConvexValue :: Int64 ( i) ) => i as usize ,
143- _ => anyhow:: bail!( "Missing or invalid 'unzippedSizeBytes' in {fields:?}" ) ,
144- } ;
150+ fn try_from ( value : SerializedPackageSize ) -> Result < Self , Self :: Error > {
151+ let zipped_size_bytes: usize = value. zipped_size_bytes . try_into ( ) ?;
152+ let unzipped_size_bytes: usize = value. unzipped_size_bytes . try_into ( ) ?;
145153 Ok ( PackageSize {
146154 zipped_size_bytes,
147155 unzipped_size_bytes,
148156 } )
149157 }
150158}
151159
152- impl TryFrom < PackageSize > for ConvexObject {
160+ impl TryFrom < PackageSize > for SerializedPackageSize {
153161 type Error = anyhow:: Error ;
154162
155163 fn try_from ( value : PackageSize ) -> Result < Self , Self :: Error > {
156- obj ! (
157- "zippedSizeBytes" => ConvexValue :: Int64 ( value. zipped_size_bytes as i64 ) ,
158- "unzippedSizeBytes" => ConvexValue :: Int64 ( value. unzipped_size_bytes as i64 ) ,
159- )
164+ Ok ( SerializedPackageSize {
165+ zipped_size_bytes : value. zipped_size_bytes . try_into ( ) ? ,
166+ unzipped_size_bytes : value. unzipped_size_bytes . try_into ( ) ? ,
167+ } )
160168 }
161169}
162170
171+ codegen_convex_serialization ! ( PackageSize , SerializedPackageSize ) ;
172+
163173#[ cfg_attr( any( test, feature = "testing" ) , derive( proptest_derive:: Arbitrary ) ) ]
164174#[ derive( Debug , Clone , PartialEq , Eq , Copy , PartialOrd , Ord , Hash ) ]
165175pub struct SourcePackageId ( DeveloperDocumentId ) ;
@@ -198,87 +208,49 @@ impl From<SourcePackageId> for DeveloperDocumentId {
198208 }
199209}
200210
201- impl TryFrom < ConvexValue > for NodeVersion {
202- type Error = anyhow:: Error ;
203-
204- fn try_from ( value : ConvexValue ) -> Result < Self , Self :: Error > {
205- if let ConvexValue :: String ( s) = value {
206- s. parse ( )
207- } else {
208- Err ( anyhow:: anyhow!( "Value is not a string" ) )
209- }
210- }
211- }
212-
213- impl TryFrom < NodeVersion > for ConvexValue {
214- type Error = anyhow:: Error ;
215-
216- fn try_from ( value : NodeVersion ) -> Result < Self , Self :: Error > {
217- match value {
218- NodeVersion :: V18x => Ok ( ConvexValue :: String ( "18" . try_into ( ) ?) ) ,
219- NodeVersion :: V20x => Ok ( ConvexValue :: String ( "20" . try_into ( ) ?) ) ,
220- NodeVersion :: V22x => Ok ( ConvexValue :: String ( "22" . try_into ( ) ?) ) ,
221- }
222- }
211+ #[ derive( Serialize , Deserialize ) ]
212+ #[ serde( rename_all = "camelCase" ) ]
213+ pub struct SerializedSourcePackage {
214+ storage_key : String ,
215+ sha256 : ByteBuf ,
216+ external_package_id : Option < String > ,
217+ package_size : Option < SerializedPackageSize > ,
218+ node_version : Option < String > ,
223219}
224220
225- impl TryFrom < SourcePackage > for ConvexObject {
221+ impl TryFrom < SourcePackage > for SerializedSourcePackage {
226222 type Error = anyhow:: Error ;
227223
228- fn try_from (
229- SourcePackage {
230- storage_key,
231- sha256,
232- external_deps_package_id,
233- package_size,
234- node_version,
235- } : SourcePackage ,
236- ) -> Result < Self , Self :: Error > {
237- let storage_key: String = storage_key. into ( ) ;
238- obj ! (
239- "storageKey" => storage_key,
240- "sha256" => sha256,
241- "externalPackageId" => external_deps_package_id
242- . map( ConvexValue :: try_from)
243- . transpose( ) ?
244- . unwrap_or( ConvexValue :: Null ) ,
245- "packageSize" => ConvexValue :: Object ( package_size. try_into( ) ?) ,
246- "nodeVersion" => node_version
247- . map( ConvexValue :: try_from)
248- . transpose( ) ?
249- . unwrap_or( ConvexValue :: Null ) ,
250- )
224+ fn try_from ( value : SourcePackage ) -> anyhow:: Result < Self > {
225+ Ok ( SerializedSourcePackage {
226+ storage_key : value. storage_key . into ( ) ,
227+ sha256 : ByteBuf :: from ( value. sha256 . to_vec ( ) ) ,
228+ external_package_id : value
229+ . external_deps_package_id
230+ . map ( |id| DeveloperDocumentId :: from ( id) . encode ( ) ) ,
231+ package_size : Some ( value. package_size . try_into ( ) ?) ,
232+ node_version : value. node_version . map ( String :: from) ,
233+ } )
251234 }
252235}
253-
254- impl TryFrom < ConvexObject > for SourcePackage {
236+ impl TryFrom < SerializedSourcePackage > for SourcePackage {
255237 type Error = anyhow:: Error ;
256238
257- fn try_from ( value : ConvexObject ) -> Result < Self , Self :: Error > {
258- let mut object_fields: BTreeMap < _ , _ > = value. into ( ) ;
259- let storage_key = match object_fields. remove ( "storageKey" ) {
260- Some ( ConvexValue :: String ( key) ) => String :: from ( key) . try_into ( ) ?,
261- _ => anyhow:: bail!( "Missing 'storageKey' in {object_fields:?}" ) ,
262- } ;
263- let sha256 = match object_fields. remove ( "sha256" ) {
264- Some ( sha256) => sha256. try_into ( ) ?,
265- _ => anyhow:: bail!( "Missing 'sha256' in {object_fields:?}" ) ,
239+ fn try_from ( value : SerializedSourcePackage ) -> Result < Self , Self :: Error > {
240+ let storage_key = value. storage_key . try_into ( ) ?;
241+ let sha256 = value. sha256 . into_vec ( ) . try_into ( ) ?;
242+ let external_package_id = match value. external_package_id {
243+ None => None ,
244+ Some ( s) => Some ( DeveloperDocumentId :: decode ( & s) ?. into ( ) ) ,
266245 } ;
267- let external_package_id = match object_fields. remove ( "externalPackageId" ) {
268- Some ( ConvexValue :: Null ) | None => None ,
269- Some ( ConvexValue :: String ( s) ) => Some ( DeveloperDocumentId :: decode ( & s) ?. into ( ) ) ,
270- _ => anyhow:: bail!( "Invalid 'externalPackageId' in {object_fields:?}" ) ,
271- } ;
272- let package_size: PackageSize = match object_fields. remove ( "packageSize" ) {
273- Some ( ConvexValue :: Object ( o) ) => o. try_into ( ) ?,
246+ let package_size: PackageSize = match value. package_size {
247+ Some ( o) => o. try_into ( ) ?,
274248 // Just use default for old source packages
275249 None => PackageSize :: default ( ) ,
276- _ => anyhow:: bail!( "Invalid 'packageSize' in {object_fields:?}" ) ,
277250 } ;
278- let node_version = match object_fields. remove ( "nodeVersion" ) {
279- Some ( ConvexValue :: Null ) | None => None ,
280- Some ( ConvexValue :: String ( s) ) => Some ( s. parse ( ) ?) ,
281- _ => anyhow:: bail!( "Invalid 'nodeVersion' in {object_fields:?}" ) ,
251+ let node_version = match value. node_version {
252+ None => None ,
253+ Some ( s) => Some ( s. parse ( ) ?) ,
282254 } ;
283255 Ok ( Self {
284256 storage_key,
@@ -290,14 +262,24 @@ impl TryFrom<ConvexObject> for SourcePackage {
290262 }
291263}
292264
265+ codegen_convex_serialization ! ( SourcePackage , SerializedSourcePackage ) ;
266+
293267#[ cfg( test) ]
294268mod tests {
295269 use cmd_util:: env:: env_config;
296270 use common:: testing:: assert_roundtrips;
297271 use proptest:: prelude:: * ;
298- use value:: ConvexObject ;
272+ use value:: {
273+ sha256:: Sha256Digest ,
274+ ConvexObject ,
275+ DeveloperDocumentId ,
276+ } ;
299277
300278 use super :: SourcePackage ;
279+ use crate :: {
280+ external_packages:: types:: ExternalDepsPackageId ,
281+ source_packages:: types:: PackageSize ,
282+ } ;
301283
302284 proptest ! {
303285 #![ proptest_config(
@@ -308,4 +290,32 @@ mod tests {
308290 assert_roundtrips:: <SourcePackage , ConvexObject >( v) ;
309291 }
310292 }
293+
294+ #[ test]
295+ fn test_frozen_source_package ( ) {
296+ let value = value:: json_deserialize ( r#"{
297+ "externalPackageId":"k423gp2tq6nsw6ngwhkw72c3z17fkb5t",
298+ "packageSize":{"unzippedSizeBytes":{"$integer":"SEUHAAAAAAA="},"zippedSizeBytes":{"$integer":"QZgBAAAAAAA="}},
299+ "sha256":{"$bytes":"7WWCt6Y52N/xQ2e7Tidc6ZPAx6KAUosaxVcVcq5dbWk="},
300+ "storageKey":"fcf904d2-566c-41fc-a899-870b6a66b274"
301+ }"# ) . unwrap ( ) ;
302+ let parsed = SourcePackage :: try_from ( value) . unwrap ( ) ;
303+ assert_eq ! (
304+ parsed,
305+ SourcePackage {
306+ storage_key: "fcf904d2-566c-41fc-a899-870b6a66b274" . try_into( ) . unwrap( ) ,
307+ sha256: Sha256Digest :: from( * b"\xed \x65 \x82 \xb7 \xa6 \x39 \xd8 \xdf \xf1 \x43 \x67 \xbb \x4e \x27 \x5c \xe9 \x93 \xc0 \xc7 \xa2 \x80 \x52 \x8b \x1a \xc5 \x57 \x15 \x72 \xae \x5d \x6d \x69 " ) ,
308+ external_deps_package_id: Some ( ExternalDepsPackageId :: from(
309+ "k423gp2tq6nsw6ngwhkw72c3z17fkb5t"
310+ . parse:: <DeveloperDocumentId >( )
311+ . unwrap( )
312+ ) ) ,
313+ package_size: PackageSize {
314+ zipped_size_bytes: 104513 ,
315+ unzipped_size_bytes: 476488 ,
316+ } ,
317+ node_version: None ,
318+ }
319+ ) ;
320+ }
311321}
0 commit comments