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, AttributedBackendMessages, AuthenticatedRouteContext,
78 AuthenticatedRoutePolicy, BackendBatchForwarding, BackendBatchOutput,
79 BackendBatchProjectionError, BackendFlushReason, BackendForwarding, BackendHoldConfigError,
80 BackendHoldLimits, BackendMiddlewareOutput, CancellationPolicy, CancellationRoute,
81 EstablishmentFailurePolicy, ForwardError, ForwardedMessage, FrontendForwarding,
82 FrontendMiddlewareOutput, HeldBackendMessages, IdentityIntermediaryMiddleware,
83 InitialServerContext, Intermediary, IntermediaryAccept, IntermediaryAcceptError,
84 IntermediaryBuildError, IntermediaryBuilder, IntermediaryCancellationRegistry,
85 IntermediaryConnection, IntermediaryContexts, IntermediaryMiddleware,
86 IntermediaryMiddlewareFactory, RejectCancellation, StartupResolutionError,
87 StartupRouteResolver,
88};
89pub use pipeline::{
90 BackendProjectionError, BoundedPipeline, FrontendProjectionError, NoPipeline, OperationId,
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, ServerAuthenticationProvider,
102 ServerAuthenticationRequest, ServerAuthenticationResponse, ServerBuilder, ServerCancellation,
103 ServerConnection, ServerConnectionContext, ServerIdentity, ServerIdentityProvider,
104 ServerProtocolLimits, ServerTlsConfiguration, ServerTlsPolicy, TrustIdentity,
105 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 {}