forked from TrueCloudLab/frostfs-sdk-go
[#170] accounting: Refactor and document package functionality
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
a55ffa4796
commit
48150852f3
6 changed files with 109 additions and 63 deletions
|
@ -3,67 +3,59 @@ package accounting
|
||||||
import "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
import "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
||||||
|
|
||||||
// Decimal represents decimal number for accounting operations.
|
// Decimal represents decimal number for accounting operations.
|
||||||
|
//
|
||||||
|
// Decimal is mutually compatible with github.com/nspcc-dev/neofs-api-go/v2/accounting.Decimal
|
||||||
|
// message. See ReadFromMessageV2 / WriteToMessageV2 methods.
|
||||||
|
//
|
||||||
|
// Instances can be created using built-in var declaration.
|
||||||
|
//
|
||||||
|
// Note that direct typecast is not safe and may result in loss of compatibility:
|
||||||
|
// _ = Decimal(accounting.Decimal{}) // not recommended
|
||||||
type Decimal accounting.Decimal
|
type Decimal accounting.Decimal
|
||||||
|
|
||||||
// NewDecimal creates, initializes and returns empty Decimal instance.
|
// ReadFromMessageV2 reads Decimal from the accounting.Decimal message.
|
||||||
//
|
//
|
||||||
// Defaults:
|
// See also WriteToMessageV2.
|
||||||
// - value: 0
|
func (d *Decimal) ReadFromMessageV2(m accounting.Decimal) {
|
||||||
// - precision: 0
|
*d = Decimal(m)
|
||||||
func NewDecimal() *Decimal {
|
|
||||||
return NewDecimalFromV2(new(accounting.Decimal))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDecimalFromV2 converts v2 Decimal to Decimal.
|
// WriteToMessageV2 writes Decimal to the accounting.Decimal message.
|
||||||
|
// The message must not be nil.
|
||||||
//
|
//
|
||||||
// Nil Decimal converts to nil.
|
// See also ReadFromMessageV2.
|
||||||
func NewDecimalFromV2(d *accounting.Decimal) *Decimal {
|
func (d Decimal) WriteToMessageV2(m *accounting.Decimal) {
|
||||||
return (*Decimal)(d)
|
*m = (accounting.Decimal)(d)
|
||||||
}
|
|
||||||
|
|
||||||
// ToV2 returns the v2 Decimal message.
|
|
||||||
//
|
|
||||||
// Nil Decimal converts to nil.
|
|
||||||
func (d *Decimal) ToV2() *accounting.Decimal {
|
|
||||||
return (*accounting.Decimal)(d)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns value of the decimal number.
|
// Value returns value of the decimal number.
|
||||||
func (d *Decimal) Value() int64 {
|
//
|
||||||
return (*accounting.Decimal)(d).GetValue()
|
// Zero Decimal has zero value.
|
||||||
|
//
|
||||||
|
// See also SetValue.
|
||||||
|
func (d Decimal) Value() int64 {
|
||||||
|
return (*accounting.Decimal)(&d).GetValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetValue sets value of the decimal number.
|
// SetValue sets value of the decimal number.
|
||||||
|
//
|
||||||
|
// See also Value.
|
||||||
func (d *Decimal) SetValue(v int64) {
|
func (d *Decimal) SetValue(v int64) {
|
||||||
(*accounting.Decimal)(d).SetValue(v)
|
(*accounting.Decimal)(d).SetValue(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Precision returns precision of the decimal number.
|
// Precision returns precision of the decimal number.
|
||||||
func (d *Decimal) Precision() uint32 {
|
//
|
||||||
return (*accounting.Decimal)(d).GetPrecision()
|
// Zero Decimal has zero precision.
|
||||||
|
//
|
||||||
|
// See also SetPrecision.
|
||||||
|
func (d Decimal) Precision() uint32 {
|
||||||
|
return (*accounting.Decimal)(&d).GetPrecision()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPrecision sets precision of the decimal number.
|
// SetPrecision sets precision of the decimal number.
|
||||||
|
//
|
||||||
|
// See also Precision.
|
||||||
func (d *Decimal) SetPrecision(p uint32) {
|
func (d *Decimal) SetPrecision(p uint32) {
|
||||||
(*accounting.Decimal)(d).SetPrecision(p)
|
(*accounting.Decimal)(d).SetPrecision(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal marshals Decimal into a protobuf binary form.
|
|
||||||
func (d *Decimal) Marshal() ([]byte, error) {
|
|
||||||
return (*accounting.Decimal)(d).StableMarshal(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal unmarshalls protobuf binary representation of Decimal.
|
|
||||||
func (d *Decimal) Unmarshal(data []byte) error {
|
|
||||||
return (*accounting.Decimal)(d).Unmarshal(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON encodes Decimal to protobuf JSON format.
|
|
||||||
func (d *Decimal) MarshalJSON() ([]byte, error) {
|
|
||||||
return (*accounting.Decimal)(d).MarshalJSON()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalJSON decodes Decimal from protobuf JSON format.
|
|
||||||
func (d *Decimal) UnmarshalJSON(data []byte) error {
|
|
||||||
return (*accounting.Decimal)(d).UnmarshalJSON(data)
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,15 +3,19 @@ package accounting_test
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/accounting"
|
"github.com/nspcc-dev/neofs-sdk-go/accounting"
|
||||||
accountingtest "github.com/nspcc-dev/neofs-sdk-go/accounting/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDecimal(t *testing.T) {
|
func TestDecimalData(t *testing.T) {
|
||||||
const v, p = 4, 2
|
const v, p = 4, 2
|
||||||
|
|
||||||
d := accounting.NewDecimal()
|
var d accounting.Decimal
|
||||||
|
|
||||||
|
require.Zero(t, d.Value())
|
||||||
|
require.Zero(t, d.Precision())
|
||||||
|
|
||||||
d.SetValue(v)
|
d.SetValue(v)
|
||||||
d.SetPrecision(p)
|
d.SetPrecision(p)
|
||||||
|
|
||||||
|
@ -19,26 +23,24 @@ func TestDecimal(t *testing.T) {
|
||||||
require.EqualValues(t, p, d.Precision())
|
require.EqualValues(t, p, d.Precision())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDecimalEncoding(t *testing.T) {
|
func TestDecimalMessageV2(t *testing.T) {
|
||||||
d := accountingtest.Decimal()
|
var (
|
||||||
|
d accounting.Decimal
|
||||||
|
m v2accounting.Decimal
|
||||||
|
)
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
m.SetValue(7)
|
||||||
data, err := d.Marshal()
|
m.SetPrecision(8)
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
d2 := accounting.NewDecimal()
|
d.ReadFromMessageV2(m)
|
||||||
require.NoError(t, d2.Unmarshal(data))
|
|
||||||
|
|
||||||
require.Equal(t, d, d2)
|
require.EqualValues(t, m.GetValue(), d.Value())
|
||||||
})
|
require.EqualValues(t, m.GetPrecision(), d.Precision())
|
||||||
|
|
||||||
t.Run("json", func(t *testing.T) {
|
var m2 v2accounting.Decimal
|
||||||
data, err := d.MarshalJSON()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
d2 := accounting.NewDecimal()
|
d.WriteToMessageV2(&m2)
|
||||||
require.NoError(t, d2.UnmarshalJSON(data))
|
|
||||||
|
|
||||||
require.Equal(t, d, d2)
|
require.EqualValues(t, d.Value(), m2.GetValue())
|
||||||
})
|
require.EqualValues(t, d.Precision(), m2.GetPrecision())
|
||||||
}
|
}
|
||||||
|
|
33
accounting/doc.go
Normal file
33
accounting/doc.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Package accounting provides primitives to perform accounting operations in NeoFS.
|
||||||
|
|
||||||
|
Decimal type provides functionality to process user balances. For example, when
|
||||||
|
working with Fixed8 balance precision:
|
||||||
|
var dec accounting.Decimal
|
||||||
|
dec.SetValue(val)
|
||||||
|
dec.SetPrecision(8)
|
||||||
|
|
||||||
|
Instances can be also used to process NeoFS API V2 protocol messages
|
||||||
|
(see neo.fs.v2.accounting package in https://github.com/nspcc-dev/neofs-api).
|
||||||
|
|
||||||
|
On client side:
|
||||||
|
import "github.com/nspcc-dev/neofs-api-go/v2/accounting"
|
||||||
|
|
||||||
|
var msg accounting.Decimal
|
||||||
|
dec.WriteToMessageV2(&msg)
|
||||||
|
|
||||||
|
// send msg
|
||||||
|
|
||||||
|
On server side:
|
||||||
|
// recv msg
|
||||||
|
|
||||||
|
var dec accounting.Decimal
|
||||||
|
dec.ReadFromMessageV2(msg)
|
||||||
|
|
||||||
|
// process dec
|
||||||
|
|
||||||
|
Using package types in an application is recommended to potentially work with
|
||||||
|
different protocol versions with which these types are compatible.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package accounting
|
|
@ -8,9 +8,9 @@ import (
|
||||||
|
|
||||||
// Decimal returns random accounting.Decimal.
|
// Decimal returns random accounting.Decimal.
|
||||||
func Decimal() *accounting.Decimal {
|
func Decimal() *accounting.Decimal {
|
||||||
d := accounting.NewDecimal()
|
var d accounting.Decimal
|
||||||
d.SetValue(rand.Int63())
|
d.SetValue(rand.Int63())
|
||||||
d.SetPrecision(rand.Uint32())
|
d.SetPrecision(rand.Uint32())
|
||||||
|
|
||||||
return d
|
return &d
|
||||||
}
|
}
|
||||||
|
|
13
accounting/test/doc.go
Normal file
13
accounting/test/doc.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
Package accountingtest provides functions for convenient testing of accounting package API.
|
||||||
|
|
||||||
|
Note that importing the package into source files is highly discouraged.
|
||||||
|
|
||||||
|
Random instance generation functions can be useful when testing expects any value, e.g.:
|
||||||
|
import accountingtest "github.com/nspcc-dev/neofs-sdk-go/accounting/test"
|
||||||
|
|
||||||
|
dec := accountingtest.Decimal()
|
||||||
|
// test the value
|
||||||
|
|
||||||
|
*/
|
||||||
|
package accountingtest
|
|
@ -92,7 +92,13 @@ func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalance
|
||||||
}
|
}
|
||||||
cc.result = func(r responseV2) {
|
cc.result = func(r responseV2) {
|
||||||
resp := r.(*v2accounting.BalanceResponse)
|
resp := r.(*v2accounting.BalanceResponse)
|
||||||
res.setAmount(accounting.NewDecimalFromV2(resp.GetBody().GetBalance()))
|
|
||||||
|
if bal := resp.GetBody().GetBalance(); bal != nil {
|
||||||
|
var d accounting.Decimal
|
||||||
|
d.ReadFromMessageV2(*bal)
|
||||||
|
|
||||||
|
res.setAmount(&d)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// process call
|
// process call
|
||||||
|
|
Loading…
Reference in a new issue