sqlx_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, CITEXT                 |
15//! | `&[u8]`, `Vec<u8>`                    | BYTEA                                                |
16//! | `()`                                  | VOID                                                 |
17//! | [`PgInterval`]                        | INTERVAL                                             |
18//! | [`PgRange<T>`](PgRange)               | INT8RANGE, INT4RANGE, TSRANGE, TSTZRANGE, DATERANGE, NUMRANGE |
19//! | [`PgMoney`]                           | MONEY                                                |
20//! | [`PgLTree`]                           | LTREE                                                |
21//! | [`PgLQuery`]                          | LQUERY                                               |
22//! | [`PgCiText`]                          | CITEXT<sup>1</sup>                                   |
23//! | [`PgCube`]                            | CUBE                                                 |
24//! | [`PgPoint`]                           | POINT                                                |
25//! | [`PgLine`]                            | LINE                                                 |
26//! | [`PgLSeg`]                            | LSEG                                                 |
27//! | [`PgBox`]                             | BOX                                                  |
28//! | [`PgPath`]                            | PATH                                                 |
29//! | [`PgPolygon`]                         | POLYGON                                              |
30//! | [`PgCircle`]                          | CIRCLE                                               |
31//! | [`PgHstore`]                          | HSTORE                                               |
32//!
33//! <sup>1</sup> SQLx generally considers `CITEXT` to be compatible with `String`, `&str`, etc.,
34//! but this wrapper type is available for edge cases, such as `CITEXT[]` which Postgres
35//! does not consider to be compatible with `TEXT[]`.
36//!
37//! ### [`bigdecimal`](https://crates.io/crates/bigdecimal)
38//! Requires the `bigdecimal` Cargo feature flag.
39//!
40//! | Rust type                             | Postgres type(s)                                        |
41//! |---------------------------------------|------------------------------------------------------|
42//! | `bigdecimal::BigDecimal`              | NUMERIC                                              |
43//!
44#![doc=include_str!("bigdecimal-range.md")]
45//!
46//! ### [`rust_decimal`](https://crates.io/crates/rust_decimal)
47//! Requires the `rust_decimal` Cargo feature flag.
48//!
49//! | Rust type                             | Postgres type(s)                                        |
50//! |---------------------------------------|------------------------------------------------------|
51//! | `rust_decimal::Decimal`               | NUMERIC                                              |
52//!
53#![doc=include_str!("rust_decimal-range.md")]
54//!
55//! ### [`chrono`](https://crates.io/crates/chrono)
56//!
57//! Requires the `chrono` Cargo feature flag.
58//!
59//! | Rust type                             | Postgres type(s)                                     |
60//! |---------------------------------------|------------------------------------------------------|
61//! | `chrono::DateTime<Utc>`               | TIMESTAMPTZ                                          |
62//! | `chrono::DateTime<Local>`             | TIMESTAMPTZ                                          |
63//! | `chrono::NaiveDateTime`               | TIMESTAMP                                            |
64//! | `chrono::NaiveDate`                   | DATE                                                 |
65//! | `chrono::NaiveTime`                   | TIME                                                 |
66//! | [`PgTimeTz`]                          | TIMETZ                                               |
67//!
68//! ### [`time`](https://crates.io/crates/time)
69//!
70//! Requires the `time` Cargo feature flag.
71//!
72//! | Rust type                             | Postgres type(s)                                     |
73//! |---------------------------------------|------------------------------------------------------|
74//! | `time::PrimitiveDateTime`             | TIMESTAMP                                            |
75//! | `time::OffsetDateTime`                | TIMESTAMPTZ                                          |
76//! | `time::Date`                          | DATE                                                 |
77//! | `time::Time`                          | TIME                                                 |
78//! | [`PgTimeTz`]                          | TIMETZ                                               |
79//!
80//! ### [`uuid`](https://crates.io/crates/uuid)
81//!
82//! Requires the `uuid` Cargo feature flag.
83//!
84//! | Rust type                             | Postgres type(s)                                     |
85//! |---------------------------------------|------------------------------------------------------|
86//! | `uuid::Uuid`                          | UUID                                                 |
87//!
88//! ### [`ipnetwork`](https://crates.io/crates/ipnetwork)
89//!
90//! Requires the `ipnetwork` Cargo feature flag (takes precedence over `ipnet` if both are used).
91//!
92//! | Rust type                             | Postgres type(s)                                     |
93//! |---------------------------------------|------------------------------------------------------|
94//! | `ipnetwork::IpNetwork`                | INET, CIDR                                           |
95//! | `std::net::IpAddr`                    | INET, CIDR                                           |
96//!
97//! Note that because `IpAddr` does not support network prefixes, it is an error to attempt to decode
98//! an `IpAddr` from a `INET` or `CIDR` value with a network prefix smaller than the address' full width:
99//! `/32` for IPv4 addresses and `/128` for IPv6 addresses.
100//!
101//! `IpNetwork` does not have this limitation.
102//!
103//! ### [`ipnet`](https://crates.io/crates/ipnet)
104//!
105//! Requires the `ipnet` Cargo feature flag.
106//!
107//! | Rust type                             | Postgres type(s)                                     |
108//! |---------------------------------------|------------------------------------------------------|
109//! | `ipnet::IpNet`                        | INET, CIDR                                           |
110//! | `std::net::IpAddr`                    | INET, CIDR                                           |
111//!
112//! The same `IpAddr` limitation for smaller network prefixes applies as with `ipnet`.
113//!
114//! ### [`mac_address`](https://crates.io/crates/mac_address)
115//!
116//! Requires the `mac_address` Cargo feature flag.
117//!
118//! | Rust type                             | Postgres type(s)                                     |
119//! |---------------------------------------|------------------------------------------------------|
120//! | `mac_address::MacAddress`             | MACADDR                                              |
121//!
122//! ### [`bit-vec`](https://crates.io/crates/bit-vec)
123//!
124//! Requires the `bit-vec` Cargo feature flag.
125//!
126//! | Rust type                             | Postgres type(s)                                     |
127//! |---------------------------------------|------------------------------------------------------|
128//! | `bit_vec::BitVec`                     | BIT, VARBIT                                          |
129//!
130//! ### [`json`](https://crates.io/crates/serde_json)
131//!
132//! Requires the `json` Cargo feature flag.
133//!
134//! | Rust type                             | Postgres type(s)                                     |
135//! |---------------------------------------|------------------------------------------------------|
136//! | [`Json<T>`]                           | JSON, JSONB                                          |
137//! | `serde_json::Value`                   | JSON, JSONB                                          |
138//! | `&serde_json::value::RawValue`        | JSON, JSONB                                          |
139//!
140//! `Value` and `RawValue` from `serde_json` can be used for unstructured JSON data with
141//! Postgres.
142//!
143//! [`Json<T>`](crate::types::Json) can be used for structured JSON data with Postgres.
144//!
145//! # [Composite types](https://www.postgresql.org/docs/current/rowtypes.html)
146//!
147//! User-defined composite types are supported through a derive for `Type`.
148//!
149//! ```text
150//! CREATE TYPE inventory_item AS (
151//!     name            text,
152//!     supplier_id     integer,
153//!     price           numeric
154//! );
155//! ```
156//!
157//! ```rust,ignore
158//! #[derive(sqlx::Type)]
159//! #[sqlx(type_name = "inventory_item")]
160//! struct InventoryItem {
161//!     name: String,
162//!     supplier_id: i32,
163//!     price: BigDecimal,
164//! }
165//! ```
166//!
167//! Anonymous composite types are represented as tuples. Note that anonymous composites may only
168//! be returned and not sent to Postgres (this is a limitation of postgres).
169//!
170//! # Arrays
171//!
172//! One-dimensional arrays are supported as `Vec<T>` or `&[T]` where `T` implements `Type`.
173//!
174//! # [Enumerations](https://www.postgresql.org/docs/current/datatype-enum.html)
175//!
176//! User-defined enumerations are supported through a derive for `Type`.
177//!
178//! ```text
179//! CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
180//! ```
181//!
182//! ```rust,ignore
183//! #[derive(sqlx::Type)]
184//! #[sqlx(type_name = "mood", rename_all = "lowercase")]
185//! enum Mood { Sad, Ok, Happy }
186//! ```
187//!
188//! Rust enumerations may also be defined to be represented as an integer using `repr`.
189//! The following type expects a SQL type of `INTEGER` or `INT4` and will convert to/from the
190//! Rust enumeration.
191//!
192//! ```rust,ignore
193//! #[derive(sqlx::Type)]
194//! #[repr(i32)]
195//! enum Mood { Sad = 0, Ok = 1, Happy = 2 }
196//! ```
197//!
198//! Rust enumerations may also be defined to be represented as a string using `type_name = "text"`.
199//! The following type expects a SQL type of `TEXT` and will convert to/from the Rust enumeration.
200//!
201//! ```rust,ignore
202//! #[derive(sqlx::Type)]
203//! #[sqlx(type_name = "text")]
204//! enum Mood { Sad, Ok, Happy }
205//! ```
206//!
207//! Note that an error can occur if you attempt to decode a value not contained within the enum
208//! definition.
209//!
210
211use crate::type_info::PgTypeKind;
212use crate::{PgTypeInfo, Postgres};
213
214pub(crate) use sqlx_core::types::{Json, Type};
215
216mod array;
217mod bool;
218mod bytes;
219mod citext;
220mod float;
221mod hstore;
222mod int;
223mod interval;
224mod lquery;
225mod ltree;
226// Not behind a Cargo feature because we require JSON in the driver implementation.
227mod json;
228mod money;
229mod oid;
230mod range;
231mod record;
232mod str;
233mod text;
234mod tuple;
235mod void;
236
237#[cfg(any(feature = "chrono", feature = "time"))]
238mod time_tz;
239
240#[cfg(feature = "bigdecimal")]
241mod bigdecimal;
242
243mod cube;
244
245mod geometry;
246
247#[cfg(any(feature = "bigdecimal", feature = "rust_decimal"))]
248mod numeric;
249
250#[cfg(feature = "rust_decimal")]
251mod rust_decimal;
252
253#[cfg(feature = "chrono")]
254mod chrono;
255
256#[cfg(feature = "time")]
257mod time;
258
259#[cfg(feature = "uuid")]
260mod uuid;
261
262#[cfg(feature = "ipnet")]
263mod ipnet;
264
265#[cfg(feature = "ipnetwork")]
266mod ipnetwork;
267
268#[cfg(feature = "mac_address")]
269mod mac_address;
270
271#[cfg(feature = "bit-vec")]
272mod bit_vec;
273
274pub use array::PgHasArrayType;
275pub use citext::PgCiText;
276pub use cube::PgCube;
277pub use geometry::circle::PgCircle;
278pub use geometry::line::PgLine;
279pub use geometry::line_segment::PgLSeg;
280pub use geometry::path::PgPath;
281pub use geometry::point::PgPoint;
282pub use geometry::polygon::PgPolygon;
283pub use geometry::r#box::PgBox;
284pub use hstore::PgHstore;
285pub use interval::PgInterval;
286pub use lquery::PgLQuery;
287pub use lquery::PgLQueryLevel;
288pub use lquery::PgLQueryVariant;
289pub use lquery::PgLQueryVariantFlag;
290pub use ltree::PgLTree;
291pub use ltree::PgLTreeLabel;
292pub use ltree::PgLTreeParseError;
293pub use money::PgMoney;
294pub use oid::Oid;
295pub use range::PgRange;
296
297#[cfg(any(feature = "chrono", feature = "time"))]
298pub use time_tz::PgTimeTz;
299
300// used in derive(Type) for `struct`
301// but the interface is not considered part of the public API
302#[doc(hidden)]
303pub use record::{PgRecordDecoder, PgRecordEncoder};
304
305// Type::compatible impl appropriate for arrays
306fn array_compatible<E: Type<Postgres> + ?Sized>(ty: &PgTypeInfo) -> bool {
307    // we require the declared type to be an _array_ with an
308    // element type that is acceptable
309    if let PgTypeKind::Array(element) = &ty.kind() {
310        return E::compatible(element);
311    }
312
313    false
314}