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