Metadata-Version: 2.4
Name: msgspec-extras
Version: 0.1.0
Project-URL: Homepage, https://pypi.org/project/msgspec-extras
Project-URL: Issues, https://codefloe.com/buriedincode/msgspec-extras/issues
Project-URL: Source, https://codefloe.com/buriedincode/msgspec-extras
Author-email: BuriedInCode <buriedincode@duckpond.nz>
Maintainer-email: BuriedInCode <buriedincode@duckpond.nz>
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: msgspec>=0.21.0
Description-Content-Type: text/markdown

# msgspec-extras

[![PyPI - Python](https://img.shields.io/pypi/pyversions/msgspec-extras.svg?logo=Python&label=Python&style=flat-square)](https://pypi.org/p/msgspec-extras/)
[![PyPI - Status](https://img.shields.io/pypi/status/msgspec-extras.svg?logo=Python&label=Status&style=flat-square)](https://pypi.org/p/msgspec-extras/)
[![PyPI - Version](https://img.shields.io/pypi/v/msgspec-extras.svg?logo=Python&label=Version&style=flat-square)](https://pypi.org/p/msgspec-extras/)
[![PyPI - License](https://img.shields.io/pypi/l/msgspec-extras.svg?logo=Python&label=License&style=flat-square)](https://opensource.org/licenses/MIT)

[![prek](https://img.shields.io/badge/prek-enabled-informational?logo=prek&style=flat-square)](https://github.com/j178/prek)
[![Ruff](https://img.shields.io/badge/Ruff-enabled-informational?logo=ruff&style=flat-square)](https://github.com/astral-sh/ruff)
[![ty](https://img.shields.io/badge/ty-enabled-informational?logo=ruff&style=flat-square)](https://github.com/astral-sh/ty)

[![status-badge](https://ci.codefloe.com/api/v1/badges/1187/status.svg)](https://ci.codefloe.com/repos/1187)

A small collection of types that extend [msgspec](https://msgspec.dev)'s built-in type support.

## Installation

```sh
pdm add msgspec-extras
```

## Type Support

`msgspec-extras` supports **all msgspec native types** - see the full list in the [msgspec documentation](https://msgspec.dev/supported-types).
It also adds the following custom types.

### Datetime

- `PastDate` - must be earlier than today
- `PastDatetime` - must be earlier than now
- `FutureDate` - must be later than today
- `FutureDatetime` - must be later than now

These types require the `enc_hook`/`dec_hook` to be passed to msgspec's encode/decode calls.

```python
from datetime import datetime, date

import msgspec
from msgspec_extras import PastDate, PastDatetime, FutureDate, FutureDatetime, enc_hook, dec_hook

past_date = msgspec.json.decode('"2020-03-21"', type=PastDate, dec_hook=dec_hook)
past_date_json = msgspec.json.encode(past_date, enc_hook=enc_hook)

msgspec.json.decode('"2020-03-21"', type=FutureDate, dec_hook=dec_hook)
# Raises `msgspec.ValidationError` as the date isn't in the future
```

### Numeric

| Type               | Constraint |
| ------------------ | ---------- |
| `PositiveInt`      | `> 0`      |
| `PositiveFloat`    | `> 0`      |
| `NonNegativeInt`   | `>= 0`     |
| `NonNegativeFloat` | `>= 0`     |
| `NegativeInt`      | `< 0`      |
| `NegativeFloat`    | `< 0`      |
| `NonPositiveInt`   | `<= 0`     |
| `NonPositiveFloat` | `<= 0`     |

### String

- `HttpUrl` - must be a valid HTTP or HTTPS URL

## Usage

The numeric and string types are just `Annotated` aliases over msgspec's native types (e.g. `Annotated[int, msgspec.Meta(gt=0)]`), so they need no hooks and work as drop-in replacements anywhere you'd use `int`, `float`, or `str`:

```python
import msgspec
from msgspec_extras import PositiveFloat


class Product(msgspec.Struct):
    name: str
    price: PositiveFloat


product = msgspec.json.decode(b'{"name": "Widget", "price": 5.1}', type=Product)
msgspec.json.encode(product)
```

## Socials

[![Social - Matrix](https://img.shields.io/matrix/The-Dev-Environment:matrix.org?label=The-Dev-Environment&logo=matrix&style=for-the-badge)](https://matrix.to/#/#The-Dev-Environment:matrix.org)
