@@ -46,7 +46,80 @@ func ContainsOperator(operators []string, operator string) bool {
4646 return false
4747}
4848
49+ func validateJsonStructure (schemaFields map [string ]interface {}, jsonData map [string ]interface {}) bool {
50+ // Ensure every field in schema is present in the JSON
51+ for key , fieldType := range schemaFields {
52+ if jsonValue , exists := jsonData [key ]; exists {
53+ switch ft := fieldType .(type ) {
54+ case string :
55+ if ! validateFieldType (ft , jsonValue ) {
56+ fmt .Printf ("Field '%s' has mismatched type or invalid value.\n " , key )
57+ return false
58+ }
59+ case map [string ]interface {}:
60+ if nestedJsonData , ok := jsonValue .(map [string ]interface {}); ok {
61+ if ! validateJsonStructure (ft , nestedJsonData ) {
62+ fmt .Printf ("Field '%s' has mismatched structure.\n " , key )
63+ return false
64+ }
65+ } else {
66+ fmt .Printf ("Expected nested structure for '%s', got something else.\n " , key )
67+ return false
68+ }
69+ default :
70+ fmt .Printf ("Unsupported type for '%s'.\n " , key )
71+ return false
72+ }
73+ } else {
74+ // Error when a required field is missing from JSON data
75+ fmt .Printf ("Field '%s' is missing from the JSON data.\n " , key )
76+ return false
77+ }
78+ }
79+
80+ // Check for extra fields in the JSON that aren't in the schema
81+ for key := range jsonData {
82+ if _ , exists := schemaFields [key ]; ! exists {
83+ fmt .Printf ("Extra field '%s' found in the JSON data but not in the schema.\n " , key )
84+ return false
85+ }
86+ }
87+
88+ return true
89+ }
90+
91+ // Validate individual field types
92+ func validateFieldType (fieldType string , value interface {}) bool {
93+ switch fieldType {
94+ case "string" :
95+ _ , ok := value .(string )
96+ return ok
97+ case "int" :
98+ _ , ok := value .(float64 ) // JSON unmarshalling in Go converts numbers to float64
99+ return ok
100+ case "uint" :
101+ val , ok := value .(float64 )
102+ return ok && val >= 0
103+ case "bytes" :
104+ _ , ok := value .(string ) // Assuming bytes are encoded as base64 strings
105+ return ok
106+ default :
107+ return false
108+ }
109+ }
110+
49111func DynamicUnmarshal (schemaDef types.SchemaDef , jsonData string ) (string , error ) {
112+ // Temporarily unmarshal JSON into a map to validate structure
113+ var tempData map [string ]interface {}
114+ if err := json .Unmarshal ([]byte (jsonData ), & tempData ); err != nil {
115+ return "error" , fmt .Errorf ("failed to unmarshal JSON for validation: %w" , err )
116+ }
117+
118+ // Validate JSON against struct definition
119+ if ! validateJsonStructure (schemaDef .Fields , tempData ) {
120+ return "error" , fmt .Errorf ("JSON data does not match the expected schema" )
121+ }
122+
50123 // Function to recursively create fields
51124 var createFields func (fields map [string ]interface {}) ([]reflect.StructField , error )
52125 createFields = func (fields map [string ]interface {}) ([]reflect.StructField , error ) {
@@ -93,14 +166,15 @@ func DynamicUnmarshal(schemaDef types.SchemaDef, jsonData string) (string, error
93166 // Create struct type from fields
94167 fields , err := createFields (schemaDef .Fields )
95168 if err != nil {
96- return "" , err
169+ return "error " , err
97170 }
171+
98172 structType := reflect .StructOf (fields )
99173 structInstance := reflect .New (structType ).Elem ()
100174
101175 // Unmarshal JSON into the dynamically created struct
102176 if err := json .Unmarshal ([]byte (jsonData ), structInstance .Addr ().Interface ()); err != nil {
103- return "" , fmt .Errorf ("failed to unmarshal JSON: %w" , err )
177+ return "error " , fmt .Errorf ("failed to unmarshal JSON: %w" , err )
104178 }
105179
106180 // Marshal the struct back to JSON with indentation
0 commit comments