tonkeeper / tongo

Go primitives to work with TON
MIT License
215 stars 45 forks source link

tlb support Unmarshal a cell to a message struct and opCode #279

Open studyzy opened 4 months ago

studyzy commented 4 months ago

Currently, tlb only have: func Unmarshal(c *boc.Cell, o any) error but when the Cell is a message with OpCode, I must define a struct with OpCode uint32.

What I want?

I want to have a new function:

func UnmarshalMessage(c *boc.Cell, o any) (opCode uint32, err error)

So I don't need define new message struct with OpCode.

studyzy commented 4 months ago

For example,

Old code

type TokenExcesses struct {
    QueryId uint64
}
type TokenExcessesWithOpCode struct {
    OpCode  uint32
    QueryId uint64
}
func parseTokenExcesses(rawBody string) (*TokenExcesses, error) {
    cells, err := boc.DeserializeBocHex(rawBody)
    if err != nil {
        return nil, err
    }
    //define new struct with opCode
    ex := TokenExcessesWithOpCode{}
    err = Unmarshal(cells[0], &ex)
    if err != nil {
        return nil, err
    }
    //return struct without opCode
    return &TokenExcesses{QueryId: ex.QueryId}, nil
}
func Test_Unmarshal(t *testing.T) {
    rawBody := "b5ee9c7201010101000e000018d53276db546de4efe9d175f0"
    ex, err := parseTokenExcesses(rawBody)
    assert.NoError(t, err)
    t.Logf("%+v", ex)
}

New code


type TokenExcesses struct {
    QueryId uint64
}

func newParseTokenExcesses(rawBody string) (*TokenExcesses, error) {
    cells, err := boc.DeserializeBocHex(rawBody)
    if err != nil {
        return nil, err
    }
    ex := TokenExcesses{}
    opCode, err := UnmarshalMessage(cells[0], &ex)
    if err != nil {
        return nil, err
    }
    if opCode != uint32(0xd53276db) {
        return nil, fmt.Errorf("unexpected opCode: %x", opCode)
    }
    //return struct without opCode
    return &ex, nil
}