Skip to content

Commit c7517f8

Browse files
committed
Update README.md
1 parent f6a0bd0 commit c7517f8

File tree

5 files changed

+71
-34
lines changed

5 files changed

+71
-34
lines changed

README.md

+18-10
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,29 @@
22

33
bufferfish is utility library for working with binary network messages between Rust and TypeScript, such as over WebSockets. It provides a simple API for encoding and decoding data into binary arrays, as well as generating TypeScript definitions and decoding functions from your Rust code.
44

5-
_This library has an unstable API and is missing a variety of functionality. I can't recommend using it in production, although I am using it for my own production project._
5+
_This library has an unstable API and may be missing some basic functionality. I can't recommend using it in production, although I am using it for my own production project._
66

77
## Repository Overview
88

99
There are two seperate libraries in this repo: one for Rust and one for TypeScript. Neither of the libraries have any required dependencies. The Rust version optionally uses the `unicode-width` crate for formatting buffer output when `pretty-print` is enabled.
1010

1111
The Rust library is broken into three seperate crates:
1212

13-
### /bufferfish
13+
### /rust/bufferfish
1414

1515
`bufferfish` is a re-export of the other crates, as well as a `generate` function for use in `build.rs` files in order to generate TypeScript definitions from your Rust packet ID type. This is what users will interact with directly. General tests also live here.
1616

17-
### /bufferfish-derive
17+
### /rust/bufferfish-derive
1818

1919
`bufferfish_derive` is where the proc macro code for the `#[derive(Encode)]` and `#[derive(Decode)]` macros live. These annotations implement `Encodable` and `Decodable` - respectively - for the annotated type.
2020

21-
### /bufferfish-core
21+
### /rust/bufferfish-core
2222

2323
`bufferfish_core`is the primary library implementation. Trait and type definitions, byte and cursor logic, and error handling live here.
2424

25-
TypeScript code lives alone within the `/typescript` directory.
25+
### /typescript/bufferfish
26+
27+
The TypeScript implementation lives here. The API is generally mirrored from the Rust version.
2628

2729
## Examples
2830

@@ -90,7 +92,7 @@ async fn process(steam: TcpStream) -> Result<(), Box<dyn std::error::Error>> {
9092
}
9193
```
9294

93-
# Decoding Generated Packets
95+
### Using Generated Decoding Functions (JavaScript)
9496

9597
These are built when defining a struct or enum in Rust with the `#[derive(Encode)]` macro after calling the `bufferfish::generate()` function.
9698

@@ -110,7 +112,7 @@ ws.onmessage = (event) => {
110112
}
111113
```
112114

113-
## Manually Decoding Packets
115+
### Manually Decoding a Bufferfish (JavaScript)
114116

115117
```typescript
116118
const ws = new WebSocket("ws://127.0.0.1:3000")
@@ -147,7 +149,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
147149
}
148150
```
149151

150-
### Example Generation
152+
### Codegen Example
151153

152154
```rust
153155
use bufferfish::Encode;
@@ -204,7 +206,7 @@ export const decodeJoinPacket = (bf: Bufferfish): JoinPacket => {
204206
}
205207
```
206208

207-
## Encodable Types
209+
## Encodable / Decodable Types
208210

209211
Supported Types | Decodes As
210212
--------------------------- | ---------------------
@@ -219,9 +221,11 @@ Supported Types | Decodes As
219221
`Vec<T> where T: Encodable` | `Array<T>`
220222
`T where T: Encodable` | `object` or primitive
221223

224+
_*The reverse is true for decoding._
225+
222226
## Notes
223227

224-
- I strongly recommend the usage of the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on your packet ID enum. This removes a lot of boilerplate.
228+
- I recommend using the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on enums you wish to `Encode`. This removes a lot of boilerplate.
225229
- Enums in TypeScript are often mentioned as a "bad" feature, and this is generally true when considering typical web development use-cases. In the case of a list of "op codes" mapping to dev-friendly names, however, they are actually really useful. Modern bundlers - like `esbuild` - [can actually inline them, meaning we just get integer literals in the final output.](https://sombia.com/posts/typescript-enums).
226230

227231
## Security
@@ -232,6 +236,10 @@ When reading data, you will always get the correct return type - however, you ar
232236

233237
This kind of problem should be dealt with before operating on the buffer.
234238

239+
Decoding an oversized bufferfish via the `Decode` trait will just ignore / discard the additional data, as it is only going to read specific byte lengths generated by the `Encodable` impl.
240+
241+
Decoding an undersized bufferfish will return a `BufferfishError::FailedWrite`.
242+
235243
## Contributing
236244

237245
`bufferfish` is open to contributions, however it should be noted that the library was created for my own game projects, and I am not interested in making it widely general-purpose. If you have a feature request or bug fix that you think would be useful to others, feel free to open an issue or PR either way.

rust/bufferfish-core/README.md

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
Core types, traits, and logic implementations for [bufferfish](https://github.com/robertwayne/bufferfish).
44

5-
_This project has an unstable API and is missing a variety of functionality. I can't recommend using it in production, although I am using it for my own production project._
6-
75
## Usage
86

97
See the [main project repository](https://github.com/robertwayne/bufferfish) for more details.

rust/bufferfish-derive/README.md

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
Macros for [bufferfish](https://github.com/robertwayne/bufferfish).
44

5-
_This project has an unstable API and is missing a variety of functionality. I can't recommend using it in production, although I am using it for my own production project._
6-
75
## Usage
86

97
See the [main project repository](https://github.com/robertwayne/bufferfish) for more details.

rust/bufferfish/README.md

+14-8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
`bufferfish` is utility library for working with binary network messages between Rust and TypeScript, such as over WebSockets. It provides a simple API for encoding and decoding data into binary arrays, as well as generating TypeScript definitions and decoding functions from your Rust code.
44

5-
_This library has an unstable API and is missing a variety of functionality. I can't recommend using it in production, although I am using it for my own production project._
5+
_This library has an unstable API and may be missing some basic functionality. I can't recommend using it in production, although I am using it for my own production project._
66

77
## Examples
88

@@ -70,7 +70,7 @@ async fn process(steam: TcpStream) -> Result<(), Box<dyn std::error::Error>> {
7070
}
7171
```
7272

73-
### Using Generated Packet Readers
73+
### Using Generated Decoding Functions (JavaScript)
7474

7575
```typescript
7676
const ws = new WebSocket("ws://127.0.0.1:3000")
@@ -88,7 +88,7 @@ ws.onmessage = (event) => {
8888
}
8989
```
9090

91-
### Manually Reading Packets
91+
### Manually Decoding a Bufferfish (JavaScript)
9292

9393
```typescript
9494
const ws = new WebSocket("ws://127.0.0.1:3000")
@@ -125,7 +125,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
125125
}
126126
```
127127

128-
### Example Generation
128+
### Codegen Example
129129

130130
```rust
131131
use bufferfish::Encode;
@@ -171,7 +171,7 @@ export const decodeJoinPacket = (bf: Bufferfish): JoinPacket => {
171171
}
172172
```
173173

174-
## Encodable Types
174+
# Encodable / Decodable Types
175175

176176
Supported Types | Decodes As
177177
--------------------------- | ---------------------
@@ -186,19 +186,25 @@ Supported Types | Decodes As
186186
`Vec<T> where T: Encodable` | `Array<T>`
187187
`T where T: Encodable` | `object` or primitive
188188

189+
_*The reverse is true for decoding._
190+
189191
## Notes
190192

191-
- I strongly recommend the usage of the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on your packet ID enum. This removes a lot of boilerplate.
192-
- Enums in TypeScript are often mentioned as a "bad" feature, and this is generally true when considering typical web development use-cases. In the case of a list of "op codes" mapping to dev-friendly names, however, they are actually really useful. Modern bundlers - like `esbuild` - [can actually inline them, meaning we just get integer literals in the final output.](https://sombia.com/posts/typescript-enums).
193+
- I recommend using the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on enums you wish to `Encode`. This removes a lot of boilerplate.
194+
- Enums in TypeScript are often mentioned as a "bad" feature, and this is generally true when considering typical web development use-cases. In the case of a list of "op codes", mapping to dev-friendly names, however, they are actually really useful. Modern bundlers - like `esbuild` - [can actually inline them, meaning we just get integer literals in the final output.](https://sombia.com/posts/typescript-enums).
193195

194-
## Security
196+
# Security
195197

196198
`bufferfish` functions ensure inputs are valid as a "best effort". Internal buffers are constructed with a maximum capacity _(default of 1024 bytes)_, and will fail to construct if an input would cause the internal buffer to cross that threshold.
197199

198200
When reading data, you will always get the correct return type - however, you are still subject to corrupted data if the input was incorrect but technically valid. For example, if you call `read_u8` on a buffer that contains a `u16` at the cursor position, you will get a `u8` back, as the buffer has no way to know that it was originally encoded as a `u16`. It is valid data, but will very likely be an unexpected value.
199201

200202
This kind of problem should be dealt with before operating on the buffer.
201203

204+
Decoding an oversized bufferfish via the `Decode` trait will just ignore / discard the additional data, as it is only going to read specific byte lengths generated by the `Encodable` impl.
205+
206+
Decoding an undersized bufferfish will return a `BufferfishError::FailedWrite`.
207+
202208
## Contributing
203209

204210
`bufferfish` is open to contributions, however it should be noted that the library was created for my own game projects, and I am not interested in making it widely general-purpose. If you have a feature request or bug fix that you think would be useful to others, feel free to open an issue or PR either way.

typescript/README.md

+39-12
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,63 @@
22

33
`bufferfish` is utility library for working with binary network messages between Rust and TypeScript, such as over WebSockets. It provides a simple API for encoding and decoding data into binary arrays, as well as generating TypeScript definitions and decoding functions from your Rust code.
44

5-
_This library has an unstable API and is missing a variety of functionality. I can't recommend using it in production, although I am using it for my own production project._
6-
75
See the [project repository](https://github.com/robertwayne/bufferfish) for more details, including how to interop with Rust.
86

7+
_This library has an unstable API and may be missing some basic functionality. I can't recommend using it in production, although I am using it for my own production project._
8+
99
## Examples
1010

11+
### Writing to a Bufferfish
12+
1113
```typescript
1214
import { Bufferfish } from 'bufferfish'
1315

1416
const ws = new WebSocket("ws://127.0.0.1:3000")
1517
ws.binaryType = "arraybuffer"
1618

1719
const bf = new Bufferfish()
20+
bf.writeUint8(0)
1821
bf.writeString("Hello, world!")
1922

2023
ws.send(bf.view())
2124
```
2225

23-
### Manually Decoding Packets
26+
### Reading from a Bufferfish
27+
28+
```typescript
29+
import { Bufferfish } from 'bufferfish'
30+
31+
const ws = new WebSocket("ws://127.0.0.1:3000")
32+
ws.binaryType = "arraybuffer"
33+
34+
onmessage = (event) => {
35+
const bf = new Bufferfish(event.data)
36+
const id = bf.readUint8()
37+
38+
if (id === 0) {
39+
const message = bf.readString()
40+
41+
console.log({ message }) // { message: "Hello, world!" }
42+
}
43+
}
44+
```
45+
46+
## Using Generated Decoding Functions
47+
48+
These are built when defining a struct or enum in Rust with the `#[derive(Encode)]` macro after calling the `bufferfish::generate()` function.
2449

2550
```typescript
2651
const ws = new WebSocket("ws://127.0.0.1:3000")
2752
ws.binaryType = "arraybuffer"
2853

2954
ws.onmessage = (event) => {
30-
const bf = new Bufferfish(event.data)
31-
const packetId = bf.readUint16()
55+
const bf = new Bufferfish(event.data)
56+
const packetId = bf.readUint16()
3257

3358
if (packetId === PacketId.Join) {
34-
const id = bf.readUint32()
35-
const username = bf.readString()
59+
const packet = decodeJoinPacket(bf)
3660

37-
console.log({
38-
id,
39-
username,
40-
}) // { id: 1, username: "Rob" }
61+
console.log(packet) // { id: 1, username: "Rob" }
4162
}
4263
}
4364
```
@@ -123,9 +144,11 @@ Supported Types | Decodes As
123144
`Vec<T> where T: Encodable` | `Array<T>`
124145
`T where T: Encodable` | `object` or primitive
125146

147+
_*The reverse is true for decoding._
148+
126149
## Notes
127150

128-
- I strongly recommend the usage of the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on your packet ID enum. This removes a lot of boilerplate.
151+
- I recommend using the [num_enum](https://github.com/illicitonion/num_enum) crate for deriving `IntoPrimitive` and `FromPrimitve` on enums you wish to `Encode`. This removes a lot of boilerplate.
129152
- Enums in TypeScript are often mentioned as a "bad" feature, and this is generally true when considering typical web development use-cases. In the case of a list of "op codes" mapping to dev-friendly names, however, they are actually really useful. Modern bundlers - like `esbuild` - [can actually inline them, meaning we just get integer literals in the final output.](https://sombia.com/posts/typescript-enums).
130153

131154
## Security
@@ -136,6 +159,10 @@ When reading data, you will always get the correct return type - however, you ar
136159

137160
This kind of problem should be dealt with before operating on the buffer.
138161

162+
Decoding an oversized bufferfish via the `Decode` trait will just ignore / discard the additional data, as it is only going to read specific byte lengths generated by the `Encodable` impl.
163+
164+
Decoding an undersized bufferfish will return a `BufferfishError::FailedWrite`.
165+
139166
## Contributing
140167

141168
`bufferfish` is open to contributions, however it should be noted that the library was created for my own game projects, and I am not interested in making it widely general-purpose. If you have a feature request or bug fix that you think would be useful to others, feel free to open an issue or PR either way.

0 commit comments

Comments
 (0)