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, ClientAuthenticationFuture, ClientAuthenticationResponse,
64 ClientAuthenticationSession, ClientBuilder, ClientConnection, ClientConnectionContext,
65 ClientInitialContext, ClientTlsConfig, ClientTlsConfiguration, ClientTlsError, ClientTlsPolicy,
66 ClientTlsProvider, ClientTlsStatus, ClientTransport, ConnectError, ConnectTarget,
67 ConnectionChanged, ConnectionClean, IdentityHandler, ProtocolLimitError, ProtocolLimits,
68 QueryError, ReloadableClientTls, StartupParameterError, StartupParameters,
69 TrustClientAuthentication,
70};
71pub use codec::{
72 Authentication, BackendMessage, Bind, Close, CopyResponse, DataRow, Describe, DescribeTarget,
73 DiagnosticField, DiagnosticResponse, Execute, FieldDescription, FrontendMessage, FunctionCall,
74 NegotiateProtocolVersion, Parse, RowDescription, TransactionStatus,
75};
76pub use demux::CancelKey;
77pub use intermediary_component::{
78 AllowAuthenticatedRoute, AuthenticatedRouteContext, AuthenticatedRoutePolicy,
79 BackendBatchForwarding, BackendBatchOutput, BackendBatchProjectionError, BackendFlushReason,
80 BackendForwarding, BackendHoldConfigError, BackendHoldLimits, BackendMiddlewareOutput,
81 CancellationPolicy, CancellationRoute, EstablishmentFailurePolicy, ForwardError,
82 ForwardedMessage, FrontendForwarding, FrontendMiddlewareOutput, HeldBackendMessages,
83 IdentityIntermediaryMiddleware, InitialServerContext, Intermediary, IntermediaryAccept,
84 IntermediaryAcceptError, IntermediaryBuildError, IntermediaryBuilder,
85 IntermediaryCancellationRegistry, IntermediaryConnection, IntermediaryContexts,
86 IntermediaryMiddleware, IntermediaryMiddlewareFactory, RejectCancellation,
87 StartupResolutionError, StartupRouteResolver,
88};
89pub use pipeline::{
90 BackendProjectionError, BoundedPipeline, FrontendProjectionError, NoPipeline,
91 PipelineConfigError, PipelinePolicy,
92};
93pub use pre_startup::{CertificateVerification, PreStartupMessage, SslMode, SslStrategy};
94pub use runtime_middleware::{
95 ClientMiddleware, IdentityMiddleware, MiddlewareChain, MiddlewareFactory, ServerMiddleware,
96};
97pub use server_component::{
98 AcceptError, AcceptedServerTransport, BuildServerError, CancellationRequest, DisabledServerTls,
99 IdentityServerHandler, NegotiatedServerTls, NoServerIdentity, NoServerIdentityProvider,
100 OptionalServerTls, RequiredServerTls, Server, ServerAccept, ServerAcceptFuture,
101 ServerAuthentication, ServerAuthenticationAction, ServerAuthenticationFuture,
102 ServerAuthenticationProvider, ServerAuthenticationRequest, ServerAuthenticationResponse,
103 ServerBuilder, ServerCancellation, ServerConnection, ServerConnectionContext, ServerIdentity,
104 ServerIdentityProvider, ServerProtocolLimits, ServerTlsConfiguration, ServerTlsPolicy,
105 TrustIdentity, TrustServerAuthentication,
106};
107pub use startup::{ProtocolVersion, StartupMessage};
108
109#[cfg(test)]
110extern crate self as pg_proto;
111
112#[cfg(test)]
113mod internal_tests;
114
115use std::marker::PhantomData;
116
117#[must_use = "dropping a connection abandons the PostgreSQL session"]
119#[derive(Debug)]
120pub(crate) struct Conn<Transport, Phase, Cleanliness = Pristine> {
121 transport: Option<Transport>,
122 _state: PhantomData<(Phase, Cleanliness)>,
123}
124
125impl<Transport, Phase, Cleanliness> Conn<Transport, Phase, Cleanliness> {
126 pub(crate) fn transition<NextPhase, NextCleanliness>(
127 mut self,
128 ) -> Conn<Transport, NextPhase, NextCleanliness> {
129 Conn {
130 transport: self.transport.take(),
131 _state: PhantomData,
132 }
133 }
134
135 pub(crate) fn into_transport(mut self) -> Transport {
141 self.transport
142 .take()
143 .expect("live connection has a transport")
144 }
145
146 pub(crate) fn map_transport<Next>(
152 mut self,
153 map: impl FnOnce(Transport) -> Next,
154 ) -> Conn<Next, Phase, Cleanliness> {
155 Conn {
156 transport: Some(map(self
157 .transport
158 .take()
159 .expect("live connection has a transport"))),
160 _state: PhantomData,
161 }
162 }
163
164 pub(crate) const fn transport(&self) -> &Transport {
165 match &self.transport {
166 Some(transport) => transport,
167 None => panic!("connection transport has already moved"),
168 }
169 }
170
171 pub(crate) const fn transport_mut(&mut self) -> &mut Transport {
172 match &mut self.transport {
173 Some(transport) => transport,
174 None => panic!("connection transport has already moved"),
175 }
176 }
177}
178
179impl<Transport> Conn<Transport, pre_startup::PreStartup, Pristine> {
180 pub(crate) const fn new(transport: Transport) -> Self {
182 Self {
183 transport: Some(transport),
184 _state: PhantomData,
185 }
186 }
187}
188
189#[cfg(debug_assertions)]
190impl<Transport, Phase, Cleanliness> Drop for Conn<Transport, Phase, Cleanliness> {
191 fn drop(&mut self) {
192 assert!(
193 self.transport.is_none() || std::thread::panicking(),
194 "live PostgreSQL connection dropped before a terminal transition; call into_transport() to abort deliberately"
195 );
196 }
197}
198
199#[derive(Debug)]
201pub(crate) enum Pristine {}
202
203#[derive(Debug)]
205pub(crate) enum Dirty {}