Skip to content

structurelib

PyPI-Version


Library README scraped 2024-03-11

structurelib-py

similar function to the builtin struct-library but more friendly

Installation

PyPI - Version

pip install structurelib

Examples

Example 1: Basic

python
from dataclasses import dataclass
import structurelib as sl
from structurelib.types import *

@dataclass
class MyStruct(sl.Structure):  # sl.Structure inheritance is optional
    name: str  # `string` is also possible
    value: int8

sl.dumps(MyStruct("Hello World", 8))  # b'\x0bHello World\x08'
MyStruct.dump_struct(MyStruct("Hello World", 8))  # b'\x0bHello World\x08'
sl.loads(b'\x0bHello World\x08', cls=MyStruct)  # MyStruct(name="Hello World", value=8)
MyStruct.load_struct(b'\x0bHello World\x08')  # MyStruct(name="Hello World", value=8)

Example 2: Nested Objects

python
import dataclasses
import structurelib as sl
from structurelib.types import *


@dataclasses.dataclass
class Credentials:
    name: string
    password: string


@dataclasses.dataclass
class User:
    name: string
    credentials: Credentials


instance = User("hello", Credentials("hello", "world"))
print(instance)  # User(name="hello", Credentials(name="hello", password="world"))
sld = sl.dumps(instance)
print(f"dump | {len(sld):>3} | {sld}")
loaded = sl.loads(sld, cls=User)
print(loaded)  # User(name="hello", Credentials(name="hello", password="world"))

Documentation

Supported types

You can keep it basic and continue to use the builtin types and it should work

python
class MyStruct:
    name: str
    number: int

But you can also add the additional types by importing them at the top of your file. These types can reduce the output size.

python
from structurelib.types import *

All additional types can be used without problem to replace the old ones and won't interfere with typechecking.

python
class MyStruct:
    name: string
    number: uint16
typedescriptionsizevalues
int/integerany integerdynamic-∞ - +∞
integer[n, False]integern byte0 - 28*n
integer[n, True]integern byte-28*(n-1) - 28*(n-1)
int8integer1 byte-128 - 127
int16integer2 bytes-32,768 - 32,767
int32integer4 bytes-2,147,483,648 - 2,147,483,647
int64integer8 bytes-9,223,372,036,854,775,808 - 9,223,372,036,854,775,807
uintany positive integerdynamic0 - +∞
uint8positive integer1 byte0 - 255
uint16positive integer2 bytes0 - 65,535
uint32positive integer4 bytes0 - 4,294,967,295
uint64positive integer8 bytes0 - 18,446,744,073,709,551,615
float/floatingfloating point number8 bytes-1.7e308 - 1.7e308
float32floating point number4 bytes-3.4e38 - 3.4e38
float64floating point number8 bytes-1.7e308 - 1.7e308
str/stringtext of any kinddynamic
string[n]text with encoded length nn bytes
charsingle character1 byte*0-255
bytes/binaryany binary datadynamic
binary[n]binary data with length nn nyte
bool/booleanboolean value1 byteTrue/False

Other builtin types like list, dict, set and so on are currently not supported.

dumps()

dump any object into bytes

Note: only annotations of a class are dumped and later reconstructed

python
def dumps(obj: object) -> bytes: ...

loads()

reconstructs object of cls from the dumped data

python
def loads(dump: bytes | BinaryIO, cls: Type[T]) -> T: ...

Structure-class

This class is only for convenience and wraps the dumps and loads functions.

python
class Structure:
    @classmethod
    def load_struct(cls: Type[T], dump: bytes | BinaryIO) -> T: ...
    def dump_struct(self) -> bytes: ...