1#![doc = include_str!("../README.md")]
2#![allow(
3 clippy::doc_markdown,
4 clippy::enum_variant_names,
5 clippy::redundant_pub_crate
6)]
7#![deny(private_bounds, private_interfaces, unreachable_pub)]
8
9#[allow(dead_code)]
10mod auth;
11mod backend_hold;
12#[allow(dead_code)]
13mod cancel;
14#[allow(dead_code)]
15mod cleanliness;
16mod client_component;
17#[allow(dead_code)]
18mod codec;
19#[allow(dead_code)]
20mod credentials;
21#[allow(dead_code)]
22mod demux;
23#[allow(dead_code)]
24mod erased;
25#[allow(dead_code)]
26mod grammar;
27#[allow(dead_code)]
28mod integrations;
29#[allow(dead_code)]
30mod intermediary;
31mod intermediary_component;
32#[allow(dead_code)]
33mod middleware;
34#[allow(dead_code)]
35mod net;
36#[allow(dead_code)]
37mod pipeline;
38#[allow(dead_code)]
39mod pre_startup;
40#[allow(dead_code)]
41mod replication;
42#[allow(dead_code)]
43mod resources;
44mod runtime_middleware;
45#[allow(dead_code)]
46mod scram;
47#[allow(dead_code)]
48mod server_auth;
49mod server_component;
50#[allow(dead_code)]
51mod server_session;
52#[allow(dead_code)]
53mod session;
54#[allow(dead_code)]
55mod startup;
56#[allow(dead_code)]
57mod tls;
58#[allow(dead_code)]
59mod transport;
60
61pub use client_component::{
62 BuildError, CancelError, Client, ClientAuthentication, ClientAuthenticationChallenge,
63 ClientAuthenticationError, ClientAuthenticationResponse, ClientAuthenticationSession,
64 ClientBuilder, ClientConnection, ClientConnectionContext, ClientInitialContext,
65 ClientTlsConfig, ClientTlsConfiguration, ClientTlsError, ClientTlsPolicy, ClientTlsProvider,
66 ClientTlsStatus, ClientTransport, ConnectError, ConnectTarget, ConnectionChanged,
67 ConnectionClean, IdentityHandler, ProtocolLimitError, ProtocolLimits, QueryError,
68 ReloadableClientTls, StartupParameterError, StartupParameters, TrustClientAuthentication,
69};
70pub use codec::{
71 Authentication, BackendMessage, Bind, Close, CopyResponse, DataRow, Describe, DescribeTarget,
72 DiagnosticField, DiagnosticResponse, Execute, FieldDescription, FrontendMessage, FunctionCall,
73 NegotiateProtocolVersion, Parse, RowDescription, TransactionStatus,
74};
75pub use demux::CancelKey;
76pub use intermediary_component::{
77 AllowAuthenticatedRoute, AuthenticatedRouteContext, AuthenticatedRoutePolicy,
78 BackendBatchForwarding, BackendBatchOutput, BackendBatchProjectionError, BackendFlushReason,
79 BackendForwarding, BackendHoldConfigError, BackendHoldLimits, BackendMiddlewareOutput,
80 CancellationPolicy, CancellationRoute, EstablishmentFailurePolicy, ForwardError,
81 ForwardedMessage, FrontendForwarding, FrontendMiddlewareOutput, HeldBackendMessages,
82 IdentityIntermediaryMiddleware, InitialServerContext, Intermediary, IntermediaryAccept,
83 IntermediaryAcceptError, IntermediaryBuildError, IntermediaryBuilder,
84 IntermediaryCancellationRegistry, IntermediaryConnection, IntermediaryContexts,
85 IntermediaryMiddleware, IntermediaryMiddlewareFactory, RejectCancellation,
86 StartupResolutionError, StartupRouteResolver,
87};
88pub use pipeline::{
89 BackendProjectionError, BoundedPipeline, FrontendProjectionError, NoPipeline,
90 PipelineConfigError, PipelinePolicy,
91};
92pub use pre_startup::{CertificateVerification, PreStartupMessage, SslMode, SslStrategy};
93pub use runtime_middleware::{
94 ClientMiddleware, IdentityMiddleware, MiddlewareChain, MiddlewareFactory, ServerMiddleware,
95};
96pub use server_component::{
97 AcceptError, AcceptedServerTransport, BuildServerError, CancellationRequest, DisabledServerTls,
98 IdentityServerHandler, NegotiatedServerTls, NoServerIdentity, NoServerIdentityProvider,
99 OptionalServerTls, RequiredServerTls, Server, ServerAccept, ServerAcceptFuture,
100 ServerAuthentication, ServerAuthenticationAction, ServerAuthenticationProvider,
101 ServerAuthenticationRequest, ServerAuthenticationResponse, ServerBuilder, ServerCancellation,
102 ServerConnection, ServerConnectionContext, ServerIdentity, ServerIdentityProvider,
103 ServerProtocolLimits, ServerTlsConfiguration, ServerTlsPolicy, TrustIdentity,
104 TrustServerAuthentication,
105};
106pub use startup::{ProtocolVersion, StartupMessage};
107
108#[cfg(test)]
109extern crate self as pg_proto;
110
111#[cfg(test)]
112mod internal_tests;
113
114use std::marker::PhantomData;
115
116#[must_use = "dropping a connection abandons the PostgreSQL session"]
118#[derive(Debug)]
119pub(crate) struct Conn<Transport, Phase, Cleanliness = Pristine> {
120 transport: Option<Transport>,
121 _state: PhantomData<(Phase, Cleanliness)>,
122}
123
124impl<Transport, Phase, Cleanliness> Conn<Transport, Phase, Cleanliness> {
125 pub(crate) fn transition<NextPhase, NextCleanliness>(
126 mut self,
127 ) -> Conn<Transport, NextPhase, NextCleanliness> {
128 Conn {
129 transport: self.transport.take(),
130 _state: PhantomData,
131 }
132 }
133
134 pub(crate) fn into_transport(mut self) -> Transport {
140 self.transport
141 .take()
142 .expect("live connection has a transport")
143 }
144
145 pub(crate) fn map_transport<Next>(
151 mut self,
152 map: impl FnOnce(Transport) -> Next,
153 ) -> Conn<Next, Phase, Cleanliness> {
154 Conn {
155 transport: Some(map(self
156 .transport
157 .take()
158 .expect("live connection has a transport"))),
159 _state: PhantomData,
160 }
161 }
162
163 pub(crate) const fn transport(&self) -> &Transport {
164 match &self.transport {
165 Some(transport) => transport,
166 None => panic!("connection transport has already moved"),
167 }
168 }
169
170 pub(crate) const fn transport_mut(&mut self) -> &mut Transport {
171 match &mut self.transport {
172 Some(transport) => transport,
173 None => panic!("connection transport has already moved"),
174 }
175 }
176}
177
178impl<Transport> Conn<Transport, pre_startup::PreStartup, Pristine> {
179 pub(crate) const fn new(transport: Transport) -> Self {
181 Self {
182 transport: Some(transport),
183 _state: PhantomData,
184 }
185 }
186}
187
188#[cfg(debug_assertions)]
189impl<Transport, Phase, Cleanliness> Drop for Conn<Transport, Phase, Cleanliness> {
190 fn drop(&mut self) {
191 assert!(
192 self.transport.is_none() || std::thread::panicking(),
193 "live PostgreSQL connection dropped before a terminal transition; call into_transport() to abort deliberately"
194 );
195 }
196}
197
198#[derive(Debug)]
200pub(crate) enum Pristine {}
201
202#[derive(Debug)]
204pub(crate) enum Dirty {}