@@ -89,6 +89,29 @@ pub struct Bom {
8989}
9090
9191impl Bom {
92+ /// General function to parse a JSON file, fetches the `specVersion` field first then applies the right conversion.
93+ pub fn parse_from_json < R : std:: io:: Read > (
94+ mut reader : R ,
95+ ) -> Result < Self , crate :: errors:: JsonReadError > {
96+ let json: serde_json:: Value = serde_json:: from_reader ( & mut reader) ?;
97+
98+ if let Some ( version) = json. get ( "specVersion" ) {
99+ let version = version
100+ . as_str ( )
101+ . ok_or_else ( || BomError :: UnsupportedSpecVersion ( version. to_string ( ) ) ) ?;
102+
103+ match SpecVersion :: from_str ( version) ? {
104+ SpecVersion :: V1_3 => Ok ( crate :: specs:: v1_3:: bom:: Bom :: deserialize ( json) ?. into ( ) ) ,
105+ SpecVersion :: V1_4 => Ok ( crate :: specs:: v1_4:: bom:: Bom :: deserialize ( json) ?. into ( ) ) ,
106+ }
107+ } else {
108+ return Err ( BomError :: UnsupportedSpecVersion (
109+ "No field 'specVersion' found" . to_string ( ) ,
110+ )
111+ . into ( ) ) ;
112+ }
113+ }
114+
92115 /// Parse the input as a JSON document conforming to [version 1.3 of the specification](https://cyclonedx.org/docs/1.3/json/)
93116 pub fn parse_from_json_v1_3 < R : std:: io:: Read > (
94117 mut reader : R ,
@@ -568,6 +591,19 @@ mod test {
568591 use super :: * ;
569592 use pretty_assertions:: assert_eq;
570593
594+ #[ test]
595+ fn it_should_parse_json_using_function_without_suffix ( ) {
596+ let input = r#"{
597+ "bomFormat": "CycloneDX",
598+ "specVersion": "1.3",
599+ "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
600+ "version": 1,
601+ "components": []
602+ }"# ;
603+ let result = Bom :: parse_from_json ( input. as_bytes ( ) ) ;
604+ assert ! ( result. is_ok( ) ) ;
605+ }
606+
571607 #[ test]
572608 fn it_should_validate_an_empty_bom_as_passed ( ) {
573609 let bom = Bom {
0 commit comments