package parsing import ( "errors" "encoding/csv" "reflect" "strconv" ) type Employee struct { EmpID uint `csv:"Emp ID"` NamePrefix string `csv:"Name Prefix"` FirstName string `csv:"First Name"` MiddleInitial string `csv:"Middle Initial"` LastName string `csv:"Last Name"` Gender Gender `csv:"Gender"` Email string `csv:"E Mail"` FathersName string `csv:"Father's Name"` MothersName string `csv:"Mothers's Name"` MothersMaidenName string `csv:"Mother's Maiden Name"` Birthdate string `csv:"Date of Birth"` BirthTime string `csv:"Time of Birth"` WeightKg uint16 `csv:"Weight in Kgs."` JoiningDate string `csv:"Date of Joining"` JoiningQuarter Quarter `csv:"Quarter of Joining"` JoiningHalf Half `csv:"Half of Joining"` JoiningYear uint16 `csv:"Year of Joining"` JoiningMonth uint8 `csv:"Month of Joining"` JoiningMonthName Month `csv:"Month Name of Joining"` JoiningMonthNameShort MonthShort `csv:"Short Month"` JoiningMonthDay uint8 `csv:"Day of Joining"` JoiningWeekDay WeekDay `csv:"DOW of Joining"` JoiningWeekDayShort WeekDayShort `csv:"Short DOW"` YearsOfService float32 `csv:"Age in Company (Years)"` Salary uint32 `csv:"Salary"` LatestHikePercentage string `csv:"Last % Hike"` SSN string `csv:"SSN"` PhoneNumber string `csv:"Phone No."` PlaceName string `csv:"Place Name"` County string `csv:"County"` City string `csv:"City"` State string `csv:"State"` Zip uint32 `csv:"Zip"` Region string `csv:"Region"` Username string `csv:"User Name"` Password string `csv:"Password"` // Empty slot // Empty slot // Empty slot } func UnmarshalEmployees(reader *csv.Reader) ([]Employee, error) { reader.Comma = ',' headers, err := reader.Read() if err != nil { return nil, errors.New("Couldn't read the headers.") } e := Employee{} refet := reflect.TypeOf(e) tagMap := make(map[string]int) headersLength := len(headers) numFields := refet.NumField() for i := 0; i < numFields && i < headersLength; i++ { field := refet.Field(i) if field.Tag.Get("csv") == headers[i] { tagMap[field.Name] = i } } var employees []Employee for { record, err := reader.Read() if err != nil { break } employee := Employee{} reflectionValue := reflect.ValueOf(&employee).Elem() for fieldName, index := range tagMap { field := reflectionValue.FieldByName(fieldName) if field.IsValid() { switch field.Type().Name() { case "string": field.SetString(record[index]) case "uint": if intValue, err := strconv.ParseUint(record[index], 10, 64); err == nil { field.SetUint(intValue) } case "uint8": if intValue, err := strconv.ParseUint(record[index], 10, 8); err == nil { field.SetUint(intValue) } case "uint16": if intValue, err := strconv.ParseUint(record[index], 10, 16); err == nil { field.SetUint(intValue) } case "uint32": if intValue, err := strconv.ParseUint(record[index], 10, 32); err == nil { field.SetUint(intValue) } case "float32": if floatValue, err := strconv.ParseFloat(record[index], 32); err == nil { field.SetFloat(floatValue) } case "Gender": field.Set(reflect.ValueOf(Gender(rune(record[index][0])))) case "Quarter": field.Set(reflect.ValueOf(Quarter(string(record[index])))) case "Half": field.Set(reflect.ValueOf(Half(string(record[index])))) case "Month": field.Set(reflect.ValueOf(Month(string(record[index])))) case "MonthShort": field.Set(reflect.ValueOf(MonthShort(string(record[index])))) case "WeekDay": field.Set(reflect.ValueOf(WeekDay(string(record[index])))) case "WeekDayShort": field.Set(reflect.ValueOf(WeekDayShort(string(record[index])))) } } } employees = append(employees, employee) } return employees, nil }