I have two structures that are similar and I want to assign one to the other. The first one "Equipment" is the structure used to match the database. The second one "JsonEquipment" is the helper structure to parse JSON data.
Here is the example:
type Equipment struct {
ID uint
CategoryID uint
Ip string
Login string
Password string
}
type JsonEquipment struct {
ID *uint
Category *string
Ip *string
Login *string
Password *string
}
The pointers are there to check if the field is present or not in the JSON. More info: How to recognize void value and unspecified field when unmarshaling in Go?
So for the moment I created a function with many "if" to check and assign to the Equipment but I wonder if there is a better & cleaner solution.
func CreateEquipment(item JsonEquipment) (Equipment) {
e := Equipment{}
if item.ID != nil && !previousEquipment.Auto { // Is the field present & not automatic equipment
e.ID = *item.ID
}
if item.Ip != nil { // Is the field present ?
e.Ip = *item.Ip
}
if item.Login != nil { // Is the field present ?
e.Login = *item.Login
}
[...]
return e
}
I hope you grasp the idea.
This question is similar to Assign struct with another struct but is different because of the pointers => non pointers struct
What I did below works but doesn't do what I intended to. Actually my first code is the only solution to check the difference between empty field and unspecified field.
Here is the demonstration of the differences: https://play.golang.org/p/3tU6paM9Do
Fist thanks for everyone's help, and particularly to @Mihailo.
What I end up doing is having my models struct without pointers, i.e:
type Equipment struct {
ID uint
CategoryID uint
Ip string
Login string
Password string
}
and I used a JSON helper struct that has a pointer of model struct, i.e
type JsonHelper struct {
Equipments []*Equipment
[Add other structures here]
}
and finally I parsed the JSON using the JsonHelper struct:
func ParseJSON(inputPath string) JsonHelper {
// Read configuration file
content, err := ioutil.ReadFile(inputPath)
if err != nil {
log.Println("Error:", err)
}
var input JsonHelper
// Parse JSON from the configuration file
err = json.Unmarshal(content, &input)
if err != nil {
log.Print("Error: ", err)
}
return input
}
HTH
Im not sure if understood your question correctly but wouldn't something like this do the job:
type Equipment struct {
ID uint
CategoryID uint
Ip string
Login string
Password string
}
func main(){
// Grabing the equipment.
equips := getEquipment()
// Checking each equipment for its validity.
for _, e := range equips {
if (e.isValid()) {
fmt.Println(e, "is OK!")
} else {
fmt.Println(e, "is NOT OK!")
}
}
}
// getEquipment fetches the json from the file.
func getEquipment() (e []Equipment) {
raw, err := ioutil.ReadFile("./equipment.json")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
json.Unmarshal(raw, &e)
return
}
// isValid checks if the equipment has all the required fields.
func (e *Equipment) isValid() bool {
if (e.Ip == "" || e.Login == "") { // You might add more validation rules
return false
}
return true
}
Its pretty straightforward but I'm not sure what more would you want to do here.
This way you have one Equipment
struct and there's no need of the other "copy" of it containing the pointers.
You can try this code out here.