Apply the waring in nbt/README.md

This commit is contained in:
Tnze
2021-06-22 11:18:18 +08:00
parent 4e6349dfda
commit 4f9779df88
4 changed files with 74 additions and 49 deletions

View File

@ -1,11 +1,11 @@
# NBT [![Go Reference](https://pkg.go.dev/badge/github.com/Tnze/go-mc/nbt.svg)](https://pkg.go.dev/github.com/Tnze/go-mc/nbt)
This package implement the [Named Binary Tag](https://wiki.vg/NBT) format of Minecraft.
The API is very similar to the standard library `encoding/json`. If you (high probability) have used that, it is easy to use this.
This package implement the [Named Binary Tag](https://wiki.vg/NBT) format of Minecraft.
# Basic Usage
> I don't know why `Marshal` looks like that, and **I will change it** to `func Marshal(v interface{}) ([]byte, error)`.
> **Use `Encoder` is recommended now.**
The API is very similar to the standard library `encoding/json`. If you (high probability) have used that, it is easy to
use this.
## Basic Usage
For the following NBT tag:
@ -20,7 +20,6 @@ To read and write would look like:
```go
package main
import "bytes"
import "github.com/Tnze/go-mc/nbt"
type Compound struct {
@ -28,27 +27,26 @@ type Compound struct {
}
func main() {
var out bytes.Buffer
banana := Compound{Name: "Bananrama"}
_ = nbt.Marshal(&out, banana)
data, _ := nbt.Marshal(banana)
var rama Compound
_ = nbt.Unmarshal(out.Bytes(), &rama)
_ = nbt.Unmarshal(data, &rama)
}
```
# Struct field tags
## Struct field tags
There are two tags supported:
- nbt
- nbt_type
The `nbt` tag is used to change the name of the NBT Tag field, whereas the `nbt_type`
tag is used to enforce a certain NBT Tag type when it is ambiguous.
tag is used to enforce a certain NBT Tag type when it is ambiguous.
For example:
```go
type Compound struct {
LongArray []int64
@ -56,5 +54,25 @@ type Compound struct {
}
```
## Stringified NBT
You can transform SNBT string into binary NBT by using go-mc, which could be useful when parsing command, but the
reverse conversion is not supported at the moment.
```go
package main
import (
"bytes"
"github.com/Tnze/go-mc/nbt"
)
func main() {
var buf bytes.Buffer
e := nbt.NewEncoder(&buf)
err := e.WriteSNBT(`{Tnze: 1, 'sp ace': [I;1,2,3]}`)
if err != nil {
panic(err)
}
}
```

View File

@ -1,6 +1,7 @@
package nbt
import (
"bytes"
"errors"
"fmt"
"io"
@ -10,8 +11,10 @@ import (
"strings"
)
func Marshal(w io.Writer, v interface{}, optionalTagName ...string) error {
return NewEncoder(w).Encode(v, optionalTagName...)
func Marshal(v interface{}, optionalTagName ...string) ([]byte, error) {
var buf bytes.Buffer
err := NewEncoder(&buf).Encode(v, optionalTagName...)
return buf.Bytes(), err
}
type Encoder struct {

View File

@ -17,11 +17,10 @@ func TestMarshal_IntArray(t *testing.T) {
0xff, 0xff, 0xff, 0xf6,
0x00, 0x00, 0x00, 0x03,
}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
if data, err := Marshal(v); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
} else if !bytes.Equal(data, out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", data, out)
}
// Test marshal in a struct
@ -35,11 +34,10 @@ func TestMarshal_IntArray(t *testing.T) {
0x00, 0x00, 0x00, 0x03, // 3
TagEnd,
}
buf.Reset()
if err := Marshal(&buf, v2); err != nil {
if data, err := Marshal(v2); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
} else if !bytes.Equal(data, out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", data, out)
}
}
@ -51,11 +49,10 @@ func TestMarshal_FloatArray(t *testing.T) {
0xc2, 0xc8, 0x00, 0x00, // -100
0x7f, 0xc0, 0x00, 0x00, // NaN
}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
if data, err := Marshal(v); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", buf.Bytes(), out)
} else if !bytes.Equal(data, out) {
t.Errorf("output binary not right: get % 02x, want % 02x ", data, out)
}
}
@ -64,11 +61,10 @@ func TestMarshal_String(t *testing.T) {
out := []byte{TagString, 0x00, 0x00, 0, 4,
'T', 'e', 's', 't'}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
if data, err := Marshal(v); err != nil {
t.Error(err)
} else if !bytes.Equal(buf.Bytes(), out) {
t.Errorf("output binary not right: got % 02x, want % 02x ", buf.Bytes(), out)
} else if !bytes.Equal(data, out) {
t.Errorf("output binary not right: got % 02x, want % 02x ", data, out)
}
}
@ -103,12 +99,11 @@ func TestMarshal_InterfaceArray(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := &bytes.Buffer{}
err := Marshal(w, tt.args)
data, err := Marshal(tt.args)
if err != nil {
t.Error(err)
} else if !bytes.Equal(w.Bytes(), tt.want) {
t.Errorf("Marshal([]interface{}) got = % 02x, want % 02x", w.Bytes(), tt.want)
} else if !bytes.Equal(data, tt.want) {
t.Errorf("Marshal([]interface{}) got = % 02x, want % 02x", data, tt.want)
return
}
})
@ -158,12 +153,11 @@ func TestMarshal_StructArray(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := &bytes.Buffer{}
err := Marshal(w, tt.args)
data, err := Marshal(tt.args)
if err != nil {
t.Error(err)
} else if !bytes.Equal(w.Bytes(), tt.want) {
t.Errorf("Marshal([]struct{}) got = % 02x, want % 02x", w.Bytes(), tt.want)
} else if !bytes.Equal(data, tt.want) {
t.Errorf("Marshal([]struct{}) got = % 02x, want % 02x", data, tt.want)
return
}
})
@ -171,8 +165,7 @@ func TestMarshal_StructArray(t *testing.T) {
}
func TestMarshal_bigTest(t *testing.T) {
var b bytes.Buffer
err := Marshal(&b, MakeBigTestStruct(), "Level")
data, err := Marshal(MakeBigTestStruct(), "Level")
if err != nil {
t.Error(err)
}
@ -183,8 +176,8 @@ func TestMarshal_bigTest(t *testing.T) {
t.Error(err)
}
if !bytes.Equal(b.Bytes(), want) {
t.Errorf("got:\n[% 2x]\nwant:\n[% 2x]", b.Bytes(), want)
if !bytes.Equal(data, want) {
t.Errorf("got:\n[% 2x]\nwant:\n[% 2x]", data, want)
}
}
@ -194,8 +187,8 @@ func TestMarshal_map(t *testing.T) {
"Xi_Xi_Mi": {0, 0, 4, 7, 2},
}
var buf bytes.Buffer
if err := Marshal(&buf, v); err != nil {
b, err := Marshal(v)
if err != nil {
t.Fatal(err)
}
@ -204,7 +197,7 @@ func TestMarshal_map(t *testing.T) {
XXM []int32 `nbt:"Xi_Xi_Mi"`
}
if err := NewDecoder(&buf).Decode(&data); err != nil {
if err := NewDecoder(bytes.NewReader(b)).Decode(&data); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(data.Tnze, v["Tnze"]) {

View File

@ -28,13 +28,24 @@ func ExampleMarshal() {
Name string `nbt:"name"`
}{"Tnze"}
var buf bytes.Buffer
if err := Marshal(&buf, value); err != nil {
data, err := Marshal(value)
if err != nil {
panic(err)
}
fmt.Printf("% 02x ", buf.Bytes())
fmt.Printf("% 02x ", data)
// Output:
// 0a 00 00 08 00 04 6e 61 6d 65 00 04 54 6e 7a 65 00
}
func ExampleEncoder_WriteSNBT() {
var buf bytes.Buffer
if err := NewEncoder(&buf).WriteSNBT(`{ name: [Tnze, "Xi_Xi_Mi"]}`); err != nil {
panic(err)
}
fmt.Printf("% 02x ", buf.Bytes())
// Output:
// 0a 00 00 09 00 04 6e 61 6d 65 08 00 00 00 02 00 04 54 6e 7a 65 00 08 58 69 5f 58 69 5f 4d 69 00
}