Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package MTL
- import (
- "encoding/csv"
- "errors"
- "fmt"
- "github.com/kak-tus/nan"
- "golang.org/x/text/encoding/charmap"
- "io"
- "os"
- "reflect"
- "strconv"
- "strings"
- "time"
- )
- var (
- NullStrType = reflect.TypeOf(nan.NullString{})
- NullIntType = reflect.TypeOf(nan.NullInt{})
- NullTimeType = reflect.TypeOf(nan.NullTime{})
- )
- type Row struct {
- Code nan.NullString
- Number nan.NullInt
- TransactionGroupID nan.NullInt
- TransactionNumber nan.NullInt
- AuthorizationNumber nan.NullInt
- TransactionPairNumber nan.NullInt
- TransactionTypeBO nan.NullString
- TransactionTypeFE nan.NullString
- AccountNumber nan.NullString
- CardNumber nan.NullString
- LocalDateTime nan.NullTime
- TransactionDateTime nan.NullTime
- TransactionDirection nan.NullString
- TransactionCurrency nan.NullInt
- SettlementCurrency nan.NullInt
- AccountCurrency nan.NullInt
- TransactionAmount nan.NullInt
- SettlementAmount nan.NullInt
- AccountAmount nan.NullInt
- MerchantID nan.NullString
- MerchantName nan.NullString
- MerchantLocation nan.NullString
- TransactionCountry nan.NullString
- TransactionState nan.NullString
- TransactionCity nan.NullString
- TransactionPostalCode nan.NullString
- TerminalID nan.NullString
- AuthorizationApprovalCode nan.NullString
- EffectiveDate nan.NullTime
- SettlementDate nan.NullTime
- CorrespondingAccount nan.NullString
- MerchantCategoryCode nan.NullString
- AcquirerReferenceNumber nan.NullInt
- RetrievalReferenceNumber nan.NullString
- TransactionChannel nan.NullString
- AuthorizationCondition nan.NullString
- Description nan.NullString
- ExtendedTransactionCity nan.NullString
- TermNum nan.NullString
- AuthorizationData nan.NullString // nan.NullInt
- ServiceID nan.NullString
- AdditionalData nan.NullString
- }
- type Mtl []Row
- func parseRow(arr []string) (Row, error) {
- row := Row{}
- rowValues := reflect.ValueOf(&row).Elem()
- //ut := reflect.TypeOf(row).Elem()
- for i, value := range arr {
- if value == "" {
- continue
- }
- fieldValue := rowValues.Field(i)
- // validate fieldValue
- if !(fieldValue.IsValid() && fieldValue.CanSet()) {
- return Row{}, errors.New("can't validate field: " + fieldValue.Type().Name())
- }
- // parse value
- fmt.Println(fieldValue.Kind(), fieldValue.Type().Name())
- switch fieldValue.Type() {
- case NullStrType:
- fieldValue.Set(reflect.ValueOf(nan.String(value)))
- case NullIntType:
- intValue, err := strconv.Atoi(value)
- if err != nil {
- return Row{}, err
- }
- fieldValue.Set(reflect.ValueOf(nan.Int(intValue)))
- case NullTimeType:
- fieldValue.Set(reflect.ValueOf(nan.Time(time.Now())))
- default:
- return Row{}, errors.New("wtf, your field's Kind is " + fieldValue.Type().Name())
- }
- // TODO: one fieldValue.Set(reflect.ValueOf for any type (after switch)
- // TODO: validation
- }
- return row, nil
- }
- func parseMtlFile(path string) (Mtl, error) {
- content, err := readFileWin1251(path)
- if err != nil {
- return nil, err
- }
- r := csv.NewReader(strings.NewReader(content))
- r.Comma = ';'
- r.LazyQuotes = true
- r.FieldsPerRecord = -1
- records, err := r.ReadAll()
- if err != nil {
- return nil, err
- }
- for i, line := range records {
- if i == 0 {
- continue
- }
- row, err := parseRow(line)
- if err != nil {
- return nil, err
- }
- fmt.Println(len(line), line)
- fmt.Printf("%+v\n", row)
- }
- // var to store file rows
- var mtl Mtl
- return mtl, nil
- }
- func readFileWin1251(path string) (string, error) {
- // Декодировка в UTF-8
- file, err := os.Open(path)
- if err != nil {
- return "", err
- }
- defer func(f *os.File) {
- err := f.Close()
- if err != nil {
- panic(err)
- }
- }(file)
- decoder := charmap.Windows1251.NewDecoder()
- reader := decoder.Reader(file)
- bytes, err := io.ReadAll(reader)
- if err != nil {
- panic(err)
- }
- return string(bytes), nil
- }
- func TestMtlParser() {
- path := "source/MTL20200807_0003.0001"
- _, err := parseMtlFile(path)
- if err != nil {
- panic(err)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement