#unsigned-integer #postgresql #sqlx #decimal #numeric #big-decimal #fixed-size

sqlx-pg-uint

SQLx compatible types to convert between Rust unsigned integers and the PostgreSQL NUMERIC/DECIMAL type seamlessly

13 releases (8 breaking)

new 0.8.0 Oct 15, 2024
0.6.1 Sep 1, 2024

#1052 in Database interfaces

Download history 373/week @ 2024-08-15 312/week @ 2024-08-22 464/week @ 2024-08-29 71/week @ 2024-09-05 31/week @ 2024-09-12 20/week @ 2024-09-19 225/week @ 2024-09-26 88/week @ 2024-10-03 137/week @ 2024-10-10

475 downloads per month
Used in chorus

MIT license

22KB
437 lines

sqlx-pg-uint

SQLx extension to support working with Rust unsigned integers in PostgreSQL.


This crate provides types with sqlx::{Encode, Decode, Type} implemented for them, which allow you to work with fixed-size unsigned integers in PostgreSQL.

use sqlx_pg_uint::PgU64;

fn main() {
    let a_u64_number = 2937854645u64;
    let pg_u_64 = PgU64::from(a_u64_number);
    println!("PgU64: {}", pg_u_64);
    let back_to_u64: u64 = pg_u_64.to_uint();
    println!("Back to u64: {}", back_to_u64);
    println!(
        "Maths work the same way as you'd expect: {}",
        PgU64::from(67) + PgU64::from(2) * PgU64::from(3) / PgU64::from(3)
    );
    println!(
        "Interact with the underlying BigDecimal type directly: {}",
        pg_u_64.as_big_decimal()
    );
    println!("PgUint types can be converted to and from BigDecimals, and are storable in an sqlx::Postgres database.");
    println!("If you load a PgUint from a database successfully, you can be sure that it's a valid fixed-size unsigned integer.");
}

When defining a column for a PostgreSQL table, which should store a fixed-size unsigned integer, you should use the NUMERIC type.

Rust Type PostgreSQL Type
PgU8 NUMERIC(3, 0)
PgU16 NUMERIC(5, 0)
PgU32 NUMERIC(10, 0)
PgU64 NUMERIC(20, 0)
PgU128 NUMERIC(39, 0)

Additionally, you are advised to use constraints to ensure that the value stored in the column is a valid fixed-size unsigned integer, guaranteed to be in range for the type.

CREATE TABLE my_table (
    -- `id` is an unsigned 64-bit integer in the corresponding Rust struct
    id numeric(20, 0) not null constraint chk_id_range check (id >= 0 AND id <= 18446744073709551615),
);

Constraining columns (or Rust types) to only store valid values is not a recommendation specific to this crate, but a general best practice to avoid faulty states in your application.

serde

This crate also provides serde de-/serialization, if the serde feature is enabled.

With the serde feature enabled, you can use the PgUint types in structs that you want to serialize and deserialize.

Types are serialized as their respective unsigned integer values, and deserialized using the underlying Deserialize trait implemented for BigDecimal.

MSRV

1.74.1

Dependencies

~15–25MB
~413K SLoC