Skip to content

Commit

Permalink
Merge pull request #9 from baldedelixo/feature/adding-reader-for-pix-…
Browse files Browse the repository at this point in the history
…copy-paste

feat: add `func ReadPIX(copyPaste string) Options`
  • Loading branch information
fonini authored Apr 27, 2023
2 parents 6b9c0ee + d2e34a3 commit 9a49d01
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 20 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ if err != nil {
}

fmt.Println(copyPaste) // will output: "00020126580014BR.GOV.BCB.PIX0122jonnasfonini@gmail.com0210Invoice #4520400005303986540520.675802BR5913Jonnas Fonini6005Marau62410503***50300017BR.GOV.BCB.BRCODE01051.0.06304CF13"

optionsFromCode, err := pix.ReadPix(copyPaste)
if err != nil {
panic(err)
}

fmt.Println(optionsFromCode)
```

### Generating a QR code from a Copy and Paste code
Expand Down
86 changes: 71 additions & 15 deletions pix/pix.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
//
// As a simple example:
//
// options := pix.Options{
// Name: "Jonnas Fonini",
// Key: "jonnasfonini@gmail.com",
// City: "Marau",
// Amount: 20.67, // optional
// Description: "Invoice #4", // optional
// TransactionID: "***", // optional
// }
// options := pix.Options{
// Name: "Jonnas Fonini",
// Key: "jonnasfonini@gmail.com",
// City: "Marau",
// Amount: 20.67, // optional
// Description: "Invoice #4", // optional
// TransactionID: "***", // optional
// }
//
// copyPaste, err := pix.Pix(options)
// copyPaste, err := pix.Pix(options)
//
// if err != nil {
// panic(err)
// }
//
// fmt.Println(copyPaste) // will output: "00020126580014BR.GOV.BCB.PIX0122jonnasfonini@gmail.com0210Invoice #4520400005303986540520.675802BR5913Jonnas Fonini6005Marau62410503***50300017BR.GOV.BCB.BRCODE01051.0.06304CF13"
// if err != nil {
// panic(err)
// }
//
// fmt.Println(copyPaste) // will output: "00020126580014BR.GOV.BCB.PIX0122jonnasfonini@gmail.com0210Invoice #4520400005303986540520.675802BR5913Jonnas Fonini6005Marau62410503***50300017BR.GOV.BCB.BRCODE01051.0.06304CF13"
package pix

import (
Expand Down Expand Up @@ -66,7 +65,6 @@ func Pix(options Options) (string, error) {
}

data := buildDataMap(options)

str := parseData(data)

// Add the CRC at the end
Expand Down Expand Up @@ -182,6 +180,64 @@ func parseData(data intMap) string {
return str
}

// ReadPix generates a Options struct using a copyPaste PIX code
func ReadPix(copyPaste string) (Options, error) {
data := buildUsingGuideMap(copyPaste, buildDataMap(Options{}))
options, err := readDataMap(data)
return options, err
}

func readDataMap(data intMap) (op Options, err error) {
keyMap, ok := data[26].(intMap)
if !ok {
return op, fmt.Errorf("data[26] is not (intMap)")
}
txMap := data[62].(intMap)
if txMap[5].(string) == "***" {
txMap[5] = ""
}

op = Options{
Key: keyMap[1].(string),
Description: keyMap[2].(string),
Amount: data[54].(float64),
Name: data[59].(string),
City: data[60].(string),
TransactionID: txMap[5].(string),
}

return op, err
}

func buildUsingGuideMap(copyPaste string, guide intMap) intMap {
data := make(intMap)

k := 0
for k < len(copyPaste) {
index, _ := strconv.Atoi(copyPaste[k : k+2])
k += 2

lenght, _ := strconv.Atoi(copyPaste[k : k+2])
k += 2

value := copyPaste[k : k+lenght]
k += lenght

v := reflect.ValueOf(guide[index])
switch v.Kind() {
case reflect.Map:
m := guide[index].(intMap)
data[index] = buildUsingGuideMap(value, m)
case reflect.String:
data[index] = value
case reflect.Float64:
data[index], _ = strconv.ParseFloat(value, 64)
}
}

return data
}

func sortKeys(data intMap) []int {
keys := make([]int, len(data))
i := 0
Expand Down
21 changes: 16 additions & 5 deletions pix/pix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pix

import (
"bytes"
"encoding/json"
"errors"
"image"
"testing"
Expand All @@ -12,15 +13,25 @@ import (
)

// test that input matches the value we want. If not, report an error on t.
func testValue(t *testing.T, input Options, want string) {
v, err := Pix(input)
func testValue(t *testing.T, options Options, copyPaste string) {
v, err := Pix(options)

if err != nil {
t.Errorf("Pix(%v) returned an error: %v", options, err)
}

if diff := cmp.Diff(copyPaste, v); diff != "" {
t.Errorf("Pix(%v) mismatch:\n%s", options, diff)
}

vp, err := ReadPix(copyPaste)
if err != nil {
t.Errorf("Pix(%v) returned an error: %v", input, err)
t.Errorf("ReadPix(%v) returned an error: %v", options, err)
}

if diff := cmp.Diff(want, v); diff != "" {
t.Errorf("Pix(%v) mismatch:\n%s", input, diff)
if diff := cmp.Diff(options, vp); diff != "" {
opJSON, _ := json.Marshal(options)
t.Errorf("ReadPix('%s') mismatch:\n%s", opJSON, diff)
}
}

Expand Down

0 comments on commit 9a49d01

Please sign in to comment.