sqlx_core_oldapi/postgres/types/
mod.rs

1//! Conversions between Rust and **Postgres** types.
2//!
3//! # Types
4//!
5//! | Rust type                             | Postgres type(s)                                     |
6//! |---------------------------------------|------------------------------------------------------|
7//! | `bool`                                | BOOL                                                 |
8//! | `i8`                                  | "CHAR"                                               |
9//! | `i16`                                 | SMALLINT, SMALLSERIAL, INT2                          |
10//! | `i32`                                 | INT, SERIAL, INT4                                    |
11//! | `i64`                                 | BIGINT, BIGSERIAL, INT8                              |
12//! | `f32`                                 | REAL, FLOAT4                                         |
13//! | `f64`                                 | DOUBLE PRECISION, FLOAT8                             |
14//! | `&str`, [`String`]                    | VARCHAR, CHAR(N), TEXT, NAME                         |
15//! | `&[u8]`, `Vec<u8>`                    | BYTEA                                                |
16//! | [`PgInterval`]                        | INTERVAL                                             |
17//! | [`PgRange<T>`](PgRange)               | INT8RANGE, INT4RANGE, TSRANGE, TSTZRANGE, DATERANGE, NUMRANGE |
18//! | [`PgMoney`]                           | MONEY                                                |
19//!
20//!
21//! ### [`bigdecimal`](https://crates.io/crates/bigdecimal)
22//! Requires the `bigdecimal` Cargo feature flag.
23//!
24//! | Rust type                             | Postgres type(s)                                        |
25//! |---------------------------------------|------------------------------------------------------|
26//! | `bigdecimal::BigDecimal`              | NUMERIC                                              |
27//!
28//! ### [`decimal`](https://crates.io/crates/rust_decimal)
29//! Requires the `decimal` Cargo feature flag.
30//!
31//! | Rust type                             | Postgres type(s)                                        |
32//! |---------------------------------------|------------------------------------------------------|
33//! | `rust_decimal::Decimal`               | NUMERIC                                              |
34//!
35//! ### [`chrono`](https://crates.io/crates/chrono)
36//!
37//! Requires the `chrono` Cargo feature flag.
38//!
39//! | Rust type                             | Postgres type(s)                                     |
40//! |---------------------------------------|------------------------------------------------------|
41//! | `chrono::DateTime<Utc>`               | TIMESTAMPTZ                                          |
42//! | `chrono::DateTime<Local>`             | TIMESTAMPTZ                                          |
43//! | `chrono::NaiveDateTime`               | TIMESTAMP                                            |
44//! | `chrono::NaiveDate`                   | DATE                                                 |
45//! | `chrono::NaiveTime`                   | TIME                                                 |
46//! | [`PgTimeTz`]                          | TIMETZ                                               |
47//!
48//! ### [`time`](https://crates.io/crates/time)
49//!
50//! Requires the `time` Cargo feature flag.
51//!
52//! | Rust type                             | Postgres type(s)                                     |
53//! |---------------------------------------|------------------------------------------------------|
54//! | `time::PrimitiveDateTime`             | TIMESTAMP                                            |
55//! | `time::OffsetDateTime`                | TIMESTAMPTZ                                          |
56//! | `time::Date`                          | DATE                                                 |
57//! | `time::Time`                          | TIME                                                 |
58//! | [`PgTimeTz`]                          | TIMETZ                                               |
59//!
60//! ### [`uuid`](https://crates.io/crates/uuid)
61//!
62//! Requires the `uuid` Cargo feature flag.
63//!
64//! | Rust type                             | Postgres type(s)                                     |
65//! |---------------------------------------|------------------------------------------------------|
66//! | `uuid::Uuid`                          | UUID                                                 |
67//!
68//! ### [`ipnetwork`](https://crates.io/crates/ipnetwork)
69//!
70//! Requires the `ipnetwork` Cargo feature flag.
71//!
72//! | Rust type                             | Postgres type(s)                                     |
73//! |---------------------------------------|------------------------------------------------------|
74//! | `ipnetwork::IpNetwork`                | INET, CIDR                                           |
75//! | `std::net::IpAddr`                    | INET, CIDR                                           |
76//!
77//! Note that because `IpAddr` does not support network prefixes, it is an error to attempt to decode
78//! an `IpAddr` from a `INET` or `CIDR` value with a network prefix smaller than the address' full width:
79//! `/32` for IPv4 addresses and `/128` for IPv6 addresses.
80//!
81//! `IpNetwork` does not have this limitation.
82//!
83//! ### [`mac_address`](https://crates.io/crates/mac_address)
84//!
85//! Requires the `mac_address` Cargo feature flag.
86//!
87//! | Rust type                             | Postgres type(s)                                     |
88//! |---------------------------------------|------------------------------------------------------|
89//! | `mac_address::MacAddress`             | MACADDR                                              |
90//!
91//! ### [`bit-vec`](https://crates.io/crates/bit-vec)
92//!
93//! Requires the `bit-vec` Cargo feature flag.
94//!
95//! | Rust type                             | Postgres type(s)                                     |
96//! |---------------------------------------|------------------------------------------------------|
97//! | `bit_vec::BitVec`                     | BIT, VARBIT                                          |
98//!
99//! ### [`json`](https://crates.io/crates/serde_json)
100//!
101//! Requires the `json` Cargo feature flag.
102//!
103//! | Rust type                             | Postgres type(s)                                     |
104//! |---------------------------------------|------------------------------------------------------|
105//! | [`Json<T>`]                           | JSON, JSONB                                          |
106//! | `serde_json::Value`                   | JSON, JSONB                                          |
107//! | `&serde_json::value::RawValue`        | JSON, JSONB                                          |
108//!
109//! `Value` and `RawValue` from `serde_json` can be used for unstructured JSON data with
110//! Postgres.
111//!
112//! [`Json<T>`](crate::types::Json) can be used for structured JSON data with Postgres.
113//!
114//! # [Composite types](https://www.postgresql.org/docs/current/rowtypes.html)
115//!
116//! User-defined composite types are supported through a derive for `Type`.
117//!
118//! ```text
119//! CREATE TYPE inventory_item AS (
120//!     name            text,
121//!     supplier_id     integer,
122//!     price           numeric
123//! );
124//! ```
125//!
126//! ```rust,ignore
127//! #[derive(sqlx::Type)]
128//! #[sqlx(type_name = "inventory_item")]
129//! struct InventoryItem {
130//!     name: String,
131//!     supplier_id: i32,
132//!     price: BigDecimal,
133//! }
134//! ```
135//!
136//! Anonymous composite types are represented as tuples. Note that anonymous composites may only
137//! be returned and not sent to Postgres (this is a limitation of postgres).
138//!
139//! # Arrays
140//!
141//! One-dimensional arrays are supported as `Vec<T>` or `&[T]` where `T` implements `Type`.
142//!
143//! # [Enumerations](https://www.postgresql.org/docs/current/datatype-enum.html)
144//!
145//! User-defined enumerations are supported through a derive for `Type`.
146//!
147//! ```text
148//! CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
149//! ```
150//!
151//! ```rust,ignore
152//! #[derive(sqlx::Type)]
153//! #[sqlx(type_name = "mood", rename_all = "lowercase")]
154//! enum Mood { Sad, Ok, Happy }
155//! ```
156//!
157//! Rust enumerations may also be defined to be represented as an integer using `repr`.
158//! The following type expects a SQL type of `INTEGER` or `INT4` and will convert to/from the
159//! Rust enumeration.
160//!
161//! ```rust,ignore
162//! #[derive(sqlx::Type)]
163//! #[repr(i32)]
164//! enum Mood { Sad = 0, Ok = 1, Happy = 2 }
165//! ```
166//!
167
168use crate::postgres::type_info::PgTypeKind;
169use crate::postgres::{PgTypeInfo, Postgres};
170use crate::types::Type;
171
172mod array;
173mod bool;
174mod bytes;
175mod float;
176mod int;
177mod interval;
178mod lquery;
179mod ltree;
180mod money;
181mod oid;
182mod range;
183mod record;
184mod str;
185mod tuple;
186mod void;
187
188#[cfg(any(feature = "chrono", feature = "time"))]
189mod time_tz;
190
191#[cfg(feature = "bigdecimal")]
192mod bigdecimal;
193
194mod numeric;
195
196#[cfg(feature = "decimal")]
197mod decimal;
198
199#[cfg(feature = "chrono")]
200mod chrono;
201
202#[cfg(feature = "time")]
203mod time;
204
205#[cfg(feature = "uuid")]
206mod uuid;
207
208#[cfg(feature = "json")]
209mod json;
210
211#[cfg(feature = "ipnetwork")]
212mod ipnetwork;
213
214#[cfg(feature = "ipnetwork")]
215mod ipaddr;
216
217#[cfg(feature = "mac_address")]
218mod mac_address;
219
220#[cfg(feature = "bit-vec")]
221mod bit_vec;
222
223pub use array::PgHasArrayType;
224pub use interval::PgInterval;
225pub use lquery::PgLQuery;
226pub use lquery::PgLQueryLevel;
227pub use lquery::PgLQueryVariant;
228pub use lquery::PgLQueryVariantFlag;
229pub use ltree::PgLTree;
230pub use ltree::PgLTreeLabel;
231pub use ltree::PgLTreeParseError;
232pub use money::PgMoney;
233pub use oid::Oid;
234pub use range::PgRange;
235
236#[cfg(any(feature = "chrono", feature = "time"))]
237pub use time_tz::PgTimeTz;
238
239// used in derive(Type) for `struct`
240// but the interface is not considered part of the public API
241#[doc(hidden)]
242pub use record::{PgRecordDecoder, PgRecordEncoder};
243
244// Type::compatible impl appropriate for arrays
245fn array_compatible<E: Type<Postgres> + ?Sized>(ty: &PgTypeInfo) -> bool {
246    // we require the declared type to be an _array_ with an
247    // element type that is acceptable
248    if let PgTypeKind::Array(element) = &ty.kind() {
249        return E::compatible(element);
250    }
251
252    false
253}