11#![ doc = include_str ! ( "../README.md" ) ]
22
33use bzip2:: bufread:: BzDecoder ;
4+ use regex:: Regex ;
45use semver:: Version ;
56use serde:: { Deserialize , Serialize } ;
67use sha1_smol:: Sha1 ;
78use std:: {
89 collections:: HashMap ,
910 fmt:: { self , Display } ,
1011 fs:: { self , File } ,
11- io:: { self , BufReader , IsTerminal } ,
12+ io:: { self , BufReader , IsTerminal , Write } ,
1213 path:: { Path , PathBuf } ,
1314 sync:: { Mutex , OnceLock } ,
1415} ;
@@ -40,6 +41,18 @@ pub enum Error {
4041 CorruptedFile ( String ) ,
4142 #[ error( "Invalid archive file path: {0}" ) ]
4243 InvalidArchiveFile ( String ) ,
44+ #[ error( "JSON serialization error: {0}" ) ]
45+ Json ( #[ from] serde_json:: Error ) ,
46+ #[ error(
47+ "Undexpected archive version: location: {location} archive {archive} expected {expected}"
48+ ) ]
49+ VersionMismatch {
50+ location : String ,
51+ archive : String ,
52+ expected : String ,
53+ } ,
54+ #[ error( "Invalid regex pattern: {0}" ) ]
55+ InvalidRegexPattern ( #[ from] regex:: Error ) ,
4356}
4457
4558pub type Result < T > = std:: result:: Result < T , Error > ;
@@ -59,20 +72,55 @@ pub const WINDOWS_TARGETS: &[&str] = &[
5972] ;
6073
6174pub fn default_version ( version : & str ) -> String {
62- static VERSIONS : OnceLock < Mutex < HashMap < String , String > > > = OnceLock :: new ( ) ;
75+ unwrap_cef_version ( version) . unwrap_or_else ( |_| version. to_string ( ) )
76+ }
77+
78+ fn unwrap_cef_version ( version : & str ) -> Result < String > {
79+ static VERSIONS : OnceLock < Mutex < HashMap < Version , String > > > = OnceLock :: new ( ) ;
6380 let mut versions = VERSIONS
6481 . get_or_init ( Default :: default)
6582 . lock ( )
6683 . expect ( "Lock error" ) ;
67- versions
68- . entry ( version. to_string ( ) )
69- . or_insert_with ( || {
70- Version :: parse ( version)
71- . ok ( )
72- . and_then ( |version| ( !version. build . is_empty ( ) ) . then ( || version. build . to_string ( ) ) )
73- . unwrap_or_else ( || version. to_string ( ) )
84+ Ok ( versions
85+ . entry ( Version :: parse ( version) ?)
86+ . or_insert_with_key ( |v| {
87+ if v. build . is_empty ( ) {
88+ version. to_string ( )
89+ } else {
90+ v. build . to_string ( )
91+ }
7492 } )
75- . clone ( )
93+ . clone ( ) )
94+ }
95+
96+ pub fn check_archive_json ( version : & str , location : & str ) -> Result < ( ) > {
97+ let expected = Version :: parse ( & unwrap_cef_version ( version) ?) ?;
98+
99+ static PATTERN : OnceLock < core:: result:: Result < Regex , regex:: Error > > = OnceLock :: new ( ) ;
100+ let pattern = PATTERN
101+ . get_or_init ( || Regex :: new ( r"^cef_binary_([^+]+)(:?\+.+)?$" ) )
102+ . as_ref ( )
103+ . map_err ( Clone :: clone) ?;
104+ let archive_json: CefFile = serde_json:: from_reader ( File :: open ( archive_json_path ( location) ) ?) ?;
105+ let archive_version = pattern. replace ( & archive_json. name , "$1" ) ;
106+ let archive = Version :: parse ( & archive_version) ?;
107+
108+ if archive == expected {
109+ Ok ( ( ) )
110+ } else {
111+ Err ( Error :: VersionMismatch {
112+ location : location. to_string ( ) ,
113+ expected : expected. to_string ( ) ,
114+ archive : archive. to_string ( ) ,
115+ } )
116+ }
117+ }
118+
119+ fn archive_json_path < P > ( location : P ) -> PathBuf
120+ where
121+ P : AsRef < Path > ,
122+ {
123+ location. as_ref ( ) . join ( "archive.json" )
76124}
77125
78126const URL : & str = "https://cef-builds.spotifycdn.com" ;
@@ -230,9 +278,19 @@ impl CefVersion {
230278 . find ( |f| f. file_type == "minimal" )
231279 . ok_or_else ( || Error :: VersionNotFound ( self . cef_version . clone ( ) ) )
232280 }
281+
282+ pub fn write_archive_json < P > ( & self , location : P ) -> Result < ( ) >
283+ where
284+ P : AsRef < Path > ,
285+ {
286+ let archive_version = serde_json:: to_string_pretty ( self . minimal ( ) ?) ?;
287+ let mut archive_json = File :: create ( archive_json_path ( location) ) ?;
288+ archive_json. write_all ( archive_version. as_bytes ( ) ) ?;
289+ Ok ( ( ) )
290+ }
233291}
234292
235- #[ derive( Deserialize , Serialize ) ]
293+ #[ derive( Eq , PartialEq , Deserialize , Serialize ) ]
236294pub struct CefFile {
237295 #[ serde( rename = "type" ) ]
238296 pub file_type : String ,
0 commit comments