package parsing import ( "encoding/csv" "errors" "reflect" "strconv" "git.cems.dev/cdricms/bdooc/ex1/proto" ) 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 "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 } func (e Employee) MapToProto() *proto.Employee { employee := &proto.Employee{} employee.EmpId = e.EmpID employee.NamePrefix = e.NamePrefix employee.FirstName = e.FirstName employee.MiddleInitial = e.MiddleInitial employee.LastName = e.LastName employee.Gender = proto.Gender(e.Gender) employee.Email = e.Email employee.FathersName = e.FathersName employee.MothersName = e.MothersName employee.MothersMaidenName = e.MothersMaidenName employee.Birthdate = e.Birthdate employee.BirthTime = e.BirthTime employee.WeightKg = uint32(e.WeightKg) employee.JoiningDate = e.JoiningDate employee.JoiningQuarter = proto.Quarter(e.JoiningQuarter.Uint8()) employee.JoiningHalf = proto.Half(e.JoiningHalf.Uint8()) employee.JoiningYear = uint32(e.JoiningYear) employee.JoiningMonth = uint32(e.JoiningMonth) employee.JoiningMonthName = proto.Month(e.JoiningMonthName.Uint8()) employee.JoiningMonthNameShort = proto.MonthShort(e.JoiningMonthNameShort.Uint8()) employee.JoiningMonthDay = uint32(e.JoiningMonthDay) employee.JoiningWeekDay = proto.WeekDay(e.JoiningWeekDay.Uint8()) employee.JoiningWeekDayShort = proto.WeekDayShort(e.JoiningWeekDayShort.Uint8()) employee.YearsOfService = float32(e.YearsOfService) employee.Salary = uint32(e.Salary) employee.LatestHikePercentage = e.LatestHikePercentage employee.Ssn = e.SSN employee.PhoneNumber = e.PhoneNumber employee.PlaceName = e.PlaceName employee.County = e.County employee.City = e.City employee.State = e.State employee.Zip = uint32(e.Zip) employee.Region = e.Region employee.Username = e.Username employee.Password = e.Password return employee } func MapToProto(es []Employee) *proto.EmployeeList { employeeList := &proto.EmployeeList{} for _, employee := range es { employeeList.Employees = append(employeeList.Employees, employee.MapToProto()) } return employeeList } func MapFromProto(e *proto.Employee) Employee { employee := Employee{} employee.EmpID = e.EmpId employee.NamePrefix = e.NamePrefix employee.FirstName = e.FirstName employee.MiddleInitial = e.MiddleInitial employee.LastName = e.LastName employee.Gender = Gender(e.Gender) employee.Email = e.Email employee.FathersName = e.FathersName employee.MothersName = e.MothersName employee.MothersMaidenName = e.MothersMaidenName employee.Birthdate = e.Birthdate employee.BirthTime = e.BirthTime employee.WeightKg = uint16(e.WeightKg) employee.JoiningDate = e.JoiningDate employee.JoiningQuarter = Quarter(e.JoiningQuarter.String()) employee.JoiningHalf = Half(e.JoiningHalf.String()) employee.JoiningYear = uint16(e.JoiningYear) employee.JoiningMonth = uint8(e.JoiningMonth) employee.JoiningMonthName = Month(e.JoiningMonthName.String()) employee.JoiningMonthNameShort = MonthShort(e.JoiningMonthNameShort.String()) employee.JoiningMonthDay = uint8(e.JoiningMonthDay) employee.JoiningWeekDay = WeekDay(e.JoiningWeekDay.String()) employee.JoiningWeekDayShort = WeekDayShort(e.JoiningWeekDayShort.String()) employee.YearsOfService = float32(e.YearsOfService) employee.Salary = uint32(e.Salary) employee.LatestHikePercentage = e.LatestHikePercentage employee.SSN = e.Ssn employee.PhoneNumber = e.PhoneNumber employee.PlaceName = e.PlaceName employee.County = e.County employee.City = e.City employee.State = e.State employee.Zip = uint32(e.Zip) employee.Region = e.Region employee.Username = e.Username employee.Password = e.Password return employee } func MapFromProtoList(el *proto.EmployeeList) []Employee { employees := []Employee{} for _, pemployee := range el.GetEmployees() { employees = append(employees, MapFromProto(pemployee)) } return employees }