feat: add data encode decode fns

This commit is contained in:
Mohamed Sohail 2024-12-19 17:23:36 +03:00
commit f87acbf98e
Signed by: kamikazechaser
GPG Key ID: 7DD45520C01CD85D
7 changed files with 138 additions and 0 deletions

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.grassecon.net/urdt/ussd-data-connect
go 1.23.3

0
go.sum Normal file
View File

22
pkg/data/decode.go Normal file
View File

@ -0,0 +1,22 @@
package data
import (
"encoding/binary"
)
const ()
// DecodeKey specifically only decodes user data keys stored as bytes into its respective session ID and data type
// TODO: Replace return data type with imported data types from the common package once lib-gdbm dependency is removed.
func DecodeKey(key []byte) (uint16, string) {
if key[0] != keyPrefix {
return 0, ""
}
return binary.BigEndian.Uint16(key[len(key)-2:]), string(key[1 : len(key)-2])
}
// DecodeValue returns the utf-8 string representation of the value stored in the storage backend
func DecodeValue(v []byte) string {
return string(v)
}

43
pkg/data/decode_test.go Normal file
View File

@ -0,0 +1,43 @@
package data
import (
"encoding/hex"
"testing"
)
func TestDecodeKey(t *testing.T) {
type want struct {
sessionID string
dataType uint16
}
type args struct {
keyBytesHex string
}
tests := []struct {
name string
args args
want want
}{
{
"blockchain_address",
args{
keyBytesHex: "202b3235343731313030303132330001",
},
want{
sessionID: "+254711000123",
dataType: ACCOUNT_BLOCKCHAIN_ADDRESS,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
keyBytes, err := hex.DecodeString(tt.args.keyBytesHex)
if err != nil {
t.Fatalf("failed to decode hex string: %v", err)
}
dataType, sessionID := DecodeKey(keyBytes)
t.Logf("%s data_type: %d, session_id: %s", tt.name, dataType, sessionID)
})
}
}

23
pkg/data/encode.go Normal file
View File

@ -0,0 +1,23 @@
package data
import (
"encoding/binary"
)
// EncodeKey returns the byte representation of a urdt/ussd user data key.
// This key can be used to lookup the value on any storage backend implementation.
// Warning: This is a shortcut specifically for user data, it is not expected to work for all go-vise keys.
// TODO: Replace with imported data types from the common package once lib-gdbm dependency is removed.
func EncodeKey(sessionID string, dataType uint16) []byte {
keyBytes := []byte(sessionID)
keyBytes = append(keyBytes, uint16ToBytes(dataType)...)
keyBytes = append([]uint8{keyPrefix}, keyBytes...)
return keyBytes
}
func uint16ToBytes(v uint16) []byte {
bytes := make([]byte, 2)
binary.BigEndian.PutUint16(bytes, v)
return bytes
}

31
pkg/data/encode_test.go Normal file
View File

@ -0,0 +1,31 @@
package data
import (
"testing"
)
// TODO: Import from urdt/ussd
func TestEncodeKey(t *testing.T) {
type args struct {
sessionID string
dataType uint16
}
tests := []struct {
name string
args args
}{
{
"blockchain_address",
args{
sessionID: "+254711000123",
dataType: ACCOUNT_BLOCKCHAIN_ADDRESS,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := EncodeKey(tt.args.sessionID, tt.args.dataType)
t.Logf("%s key: %x", tt.name, got)
})
}
}

16
pkg/data/type.go Normal file
View File

@ -0,0 +1,16 @@
package data
// Subset of urdt/ussd/common specifically for syncing to the central data store i.e Graph.
// TODO: Replace with imported data types from the common package once lib-gdbm dependency is removed.
const (
keyPrefix = 32
ACCOUNT_BLOCKCHAIN_ADDRESS = 1
ACCOUNT_FIRST_NAME = 3
ACCOUNT_LAST_NAME = 4
ACCOUNT_YOB = 5
ACCOUNT_LOCATION = 6
ACCOUNT_GENDER = 7
ACCOUNT_COMMODITIES = 8
ACCOUNT_ACTIVE_VOUCHER = 17
)