|
package main |
|
|
|
import ( |
|
"encoding/json" |
|
"errors" |
|
// "fmt" |
|
"io/ioutil" |
|
"log" |
|
"net/http" |
|
"os" |
|
) |
|
|
|
type FleetVehicle interface { |
|
// MakeAndModel() string |
|
} |
|
|
|
type Vehicle struct { |
|
Type string `json:"type"` |
|
Make string `json:"make"` |
|
Model string `json:"model"` |
|
} |
|
|
|
// func (v Vehicle) MakeAndModel() string { |
|
// return fmt.Sprintf("%s %s", v.Make, v.Model) |
|
// } |
|
|
|
type Car struct { |
|
Vehicle |
|
SeatingCapacity int `json:"seatingCapacity"` |
|
TopSpeed float64 `json:"topSpeed"` |
|
} |
|
|
|
type Truck struct { |
|
Vehicle |
|
PayloadCapacity float64 `json:"payloadCapacity"` |
|
} |
|
|
|
type Bike struct { |
|
Vehicle |
|
TopSpeed float64 `json:"topSpeed"` |
|
} |
|
|
|
type Fleet struct { |
|
Status string `json:"status"` |
|
Vehicles []FleetVehicle `json:"-"` |
|
//Vehicles []Vehicle `json:"-"` |
|
//RawVehicles []json.RawMessage |
|
RawVehicles []json.RawMessage `json:"data"` |
|
} |
|
|
|
func (f *Fleet) MarshalJSON() ([]byte, error) { |
|
|
|
type fleet Fleet |
|
|
|
if f.Vehicles != nil { |
|
for _, v := range f.Vehicles { |
|
b, err := json.Marshal(v) |
|
if err != nil { |
|
return nil, err |
|
} |
|
f.RawVehicles = append(f.RawVehicles, b) |
|
} |
|
} |
|
|
|
return json.Marshal((*fleet)(f)) |
|
} |
|
|
|
func (f *Fleet) UnmarshalJSON(b []byte) error { |
|
|
|
type fleet Fleet |
|
|
|
err := json.Unmarshal(b, (*fleet)(f)) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
for _, raw := range f.RawVehicles { |
|
|
|
var v Vehicle |
|
err = json.Unmarshal(raw, &v) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
var i FleetVehicle |
|
switch v.Type { |
|
case "car": |
|
i = &Car{} |
|
case "truck": |
|
i = &Truck{} |
|
case "bike": |
|
i = &Bike{} |
|
default: |
|
return errors.New("unknown vehicle type") |
|
} |
|
|
|
err = json.Unmarshal(raw, i) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
f.Vehicles = append(f.Vehicles, i) |
|
} |
|
|
|
return nil |
|
} |
|
func main() { |
|
http.HandleFunc("/", HelloServer) |
|
http.ListenAndServe(":8080", nil) |
|
} |
|
|
|
// type response2 struct { |
|
// Page int `json:"page"` |
|
// Fruits []string `json:"fruits"` |
|
// } |
|
|
|
func Response(w http.ResponseWriter, js []byte) { |
|
w.Header().Set("Content-Type", "application/json;charset=utf-8") |
|
w.Header().Set("Access-Control-Allow-Origin", "*") |
|
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") |
|
w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") |
|
w.Header().Set("Access-Control-Expose-Headers", "Content-Type, X-Requested-With, X-authentication, X-client") |
|
w.WriteHeader(http.StatusOK) |
|
w.Write(js) |
|
} |
|
|
|
// type ExJsonPath struct { |
|
// Status string `json:"status"` |
|
// Data Fleet `json:"data"` |
|
// } |
|
|
|
func LoadFleet(outFile string) Fleet { |
|
jsonFile, _ := os.Open(outFile) |
|
defer jsonFile.Close() |
|
byteValue, _ := ioutil.ReadAll(jsonFile) |
|
var f *Fleet |
|
err := json.Unmarshal(byteValue, &f) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
return *f |
|
} |
|
func HelloServer(w http.ResponseWriter, r *http.Request) { |
|
// fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:]) |
|
// es2D := &response2{ |
|
// Page: 1, |
|
// Fruits: []string{"apple", "peach", "pear"}} |
|
// js, _ := json.Marshal(es2D) |
|
// fleet := &Fleet{ |
|
// Vehicles: []FleetVehicle{ |
|
// &Car{Vehicle{"car", "Mercedes-Benz", "AMG C 63"}, 4, 250}, |
|
// &Bike{Vehicle{"bike", "Triumph", "Bonneville T120"}, 193.12}, |
|
// }, |
|
// } |
|
queryResult := make([]Fleet, 2) |
|
outFile := "test.json" |
|
outFile2 := "test2.json" |
|
queryResult[0] = LoadFleet(outFile) |
|
queryResult[1] = LoadFleet(outFile2) |
|
var totalLen int |
|
for _, s := range queryResult { |
|
totalLen += len(s.Vehicles) |
|
} |
|
tmp := make([]FleetVehicle, totalLen) |
|
var i int |
|
for _, s := range queryResult { |
|
i += copy(tmp[i:], s.Vehicles) |
|
} |
|
comboFleet := &Fleet{Vehicles: tmp, Status: "good"} |
|
js, _ := json.MarshalIndent(&comboFleet, "", " ") |
|
//dat := ExJsonPath("success", js) |
|
Response(w, js) |
|
} |