Commit f1f9b315 authored by Sybren A. Stüvel's avatar Sybren A. Stüvel

Struct merging works

parent 806a18b2
/bunq_credentials.yaml
/bunq_key_private.pem
bunq_credentials.yaml
bunq_key_private.pem
......@@ -11,10 +11,11 @@ type deviceServerRequest struct {
PermittedIPs []string `json:"permitted_ips"`
}
type wrappedDeviceServerResponse struct {
Response []deviceServerResponse `json:"Response"`
}
type deviceServerResponse struct {
Response []struct {
ID BunqID `json:"Id`
} `json:"Response"`
ID BunqID `json:"Id`
}
func (c *Client) CheckDeviceServer(description string, permittedIPs []string) {
......@@ -32,13 +33,15 @@ func (c *Client) PostDeviceServer(description string, permittedIPs []string) {
PermittedIPs: permittedIPs,
}
response := deviceServerResponse{}
errResp := c.DoRequest("POST", "device-server", &payload, &response)
wrappedResponse := wrappedDeviceServerResponse{}
errResp := c.DoRequest("POST", "device-server", &payload, &wrappedResponse)
if errResp != nil {
log.WithFields(errResp.LogFields()).Fatal("error performing device registration request")
}
response := deviceServerResponse{}
MergeStructs(wrappedResponse.Response, &response)
c.creds.DeviceID = response.Response[0].ID.ID
c.creds.DeviceID = response.ID.ID
logrus.WithField("id", c.creds.DeviceID).Info("registered device device ID")
c.creds.Save()
}
......@@ -17,21 +17,23 @@ type installationRequest struct {
ClientPublicKey string `json:"client_public_key"`
}
type wrappedInstallationResponse struct {
Response []installationResponse `json:"Response"`
}
type installationResponse struct {
Response []struct {
ID *BunqID `json:"Id"`
Token *struct {
ID int `json:"id"`
Created string `json:"created"`
Updated string `json:"updated"`
Token string `json:"token"`
} `json:"Token"`
ServerPublicKey *struct {
Key string `json:"server_public_key"`
} `json:"ServerPublicKey"`
} `json:"Response"`
ID *BunqID `json:"Id"`
Token *struct {
ID int `json:"id"`
Created string `json:"created"`
Updated string `json:"updated"`
Token string `json:"token"`
} `json:"Token"`
ServerPublicKey *struct {
Key string `json:"server_public_key"`
} `json:"ServerPublicKey"`
}
func publicKeyString(privateKey *rsa.PrivateKey) string {
......@@ -56,20 +58,17 @@ func (c *Client) PostInstallation() {
ClientPublicKey: publicKeyString(c.privateKey),
}
response := installationResponse{}
errResp := c.DoRequest("POST", "installation", &payload, &response)
wrappedResponse := wrappedInstallationResponse{}
errResp := c.DoRequest("POST", "installation", &payload, &wrappedResponse)
if errResp != nil {
log.WithFields(errResp.LogFields()).Fatal("error performing installation request")
}
for _, subResponse := range response.Response {
if subResponse.ServerPublicKey != nil {
c.creds.ServerPublicKey = subResponse.ServerPublicKey.Key
}
if subResponse.Token != nil {
c.creds.InstallationToken = subResponse.Token.Token
}
}
response := installationResponse{}
MergeStructs(wrappedResponse.Response, &response)
c.creds.ServerPublicKey = response.ServerPublicKey.Key
c.creds.InstallationToken = response.Token.Token
log.WithFields(logrus.Fields{
"installationToken": c.creds.InstallationToken,
......
package bunqapi
import (
"fmt"
"reflect"
)
// MergeStructs merges an array of structs into a single struct.
func MergeStructs(responses interface{}, mergedResp interface{}) {
arrayType := reflect.TypeOf(responses)
if arrayType.Kind() != reflect.Slice && arrayType.Kind() != reflect.Array {
panic(fmt.Sprintf("responses should be a slice or array, not %v", arrayType.Kind()))
}
responsesValue := reflect.ValueOf(responses)
numResponses := responsesValue.Len()
respType := arrayType.Elem()
numFields := respType.NumField()
resultType := reflect.TypeOf(mergedResp)
if resultType.Elem() != respType {
panic(fmt.Sprintf("mergedResp should be *%v, not %v", respType, reflect.TypeOf(mergedResp)))
}
resultValue := reflect.ValueOf(mergedResp).Elem()
for index := 0; index < numResponses; index++ {
// fmt.Printf("response #%d:\n", index)
responseValue := responsesValue.Index(index)
for fieldnum := 0; fieldnum < numFields; fieldnum++ {
// field := respType.Field(fieldnum)
fieldVal := responseValue.Field(fieldnum)
// Skip unexported fields.
if !fieldVal.CanSet() {
continue
}
// fmt.Printf(" - field %d: %10v ", fieldnum, field.Name)
useValue := false
switch fieldVal.Kind() {
case reflect.Ptr:
useValue = !fieldVal.IsNil()
// fmt.Printf("is pointer: %v", useValue)
case reflect.String:
useValue = fieldVal.String() != ""
// fmt.Printf("is string : %v", useValue)
case reflect.Bool:
useValue = fieldVal.Bool()
// fmt.Printf("is bool : %v", useValue)
default:
// fmt.Printf("is kind : %v (not using)", fieldVal.Kind())
}
// fmt.Println()
if !useValue {
continue
}
resultField := resultValue.Field(fieldnum)
resultField.Set(fieldVal)
}
}
}
package main
import (
"encoding/json"
"os"
"github.com/sirupsen/logrus"
"gitlab.com/dr.sybren/bunqapi"
)
type BunqResponse struct {
Response []SingleResponse
}
type SingleResponse struct {
Field1 string `json:"field1,omitempty"`
Field2 string `json:"field2,omitempty"`
SomeOb *SubOb `json:"someOb,omitempty"`
booltje bool `json:"booltje"`
}
type SubOb struct {
SubField string `json:"subfield,omitempty"`
}
func main() {
responses := []SingleResponse{
{Field1: "field1"},
{SomeOb: &SubOb{SubField: "subfield"}},
{booltje: true},
}
fromBunq := BunqResponse{
Response: responses,
}
merged := SingleResponse{}
bunqapi.MergeStructs(fromBunq.Response, &merged)
out, err := json.MarshalIndent(merged, "", " ")
if err != nil {
logrus.WithError(err).Fatal("unable to marshal result to JSON")
}
os.Stdout.Write(out)
os.Stdout.WriteString("\n")
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment