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)]
26pub mod 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, StaticClientCredentialSession,
69 StaticClientCredentials, StaticCredentialError, 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, AttributedBackendMessages, AuthenticatedRouteContext,
79 AuthenticatedRoutePolicy, BackendBatchForwarding, BackendBatchOutput,
80 BackendBatchProjectionError, BackendFlushReason, BackendForwarding, BackendHoldConfigError,
81 BackendHoldLimits, BackendMiddlewareOutput, CancellationPolicy, CancellationRoute,
82 EstablishmentFailurePolicy, ForwardError, ForwardedMessage, FrontendForwarding,
83 FrontendMiddlewareOutput, HeldBackendMessages, IdentityIntermediaryMiddleware,
84 InMemoryCancellationRegistry, InMemoryCancellationRegistryError, InitialServerContext,
85 Intermediary, IntermediaryAccept, IntermediaryAcceptError, IntermediaryBuildError,
86 IntermediaryBuilder, IntermediaryCancellationRegistry, IntermediaryConnection,
87 IntermediaryContexts, IntermediaryMiddleware, IntermediaryMiddlewareFactory,
88 RejectCancellation, StartupResolutionError, StartupRouteResolver,
89};
90pub use pipeline::{
91 BackendProjectionError, BoundedPipeline, FrontendProjectionError, NoPipeline, OperationId,
92 PipelineConfigError, PipelinePolicy,
93};
94pub use pre_startup::{CertificateVerification, PreStartupMessage, SslMode, SslStrategy};
95pub use runtime_middleware::{
96 ClientMiddleware, IdentityMiddleware, MiddlewareChain, MiddlewareFactory, ServerMiddleware,
97};
98pub use server_component::{
99 AcceptError, AcceptedServerTransport, BuildServerError, CancellationRequest, DisabledServerTls,
100 IdentityServerHandler, NegotiatedServerTls, NoServerIdentity, NoServerIdentityProvider,
101 OptionalServerTls, RequiredServerTls, Server, ServerAccept, ServerAcceptFuture,
102 ServerAuthentication, ServerAuthenticationAction, ServerAuthenticationProvider,
103 ServerAuthenticationRequest, ServerAuthenticationResponse, ServerBuilder, ServerCancellation,
104 ServerConnection, ServerConnectionContext, ServerIdentity, ServerIdentityProvider,
105 ServerProtocolLimits, ServerTlsConfiguration, ServerTlsPolicy,
106 StaticMd5ServerCredentialSession, StaticMd5ServerCredentials, TrustIdentity,
107 TrustServerAuthentication,
108};
109pub use startup::{ProtocolVersion, StartupMessage};
110
111#[cfg(test)]
112extern crate self as pg_proto;
113
114#[cfg(test)]
115mod internal_tests;
116
117use std::marker::PhantomData;
118
119#[must_use = "dropping a connection abandons the PostgreSQL session"]
121#[derive(Debug)]
122pub(crate) struct Conn<Transport, Phase, Cleanliness = Pristine> {
123 transport: Option<Transport>,
124 _state: PhantomData<(Phase, Cleanliness)>,
125}
126
127impl<Transport, Phase, Cleanliness> Conn<Transport, Phase, Cleanliness> {
128 pub(crate) fn transition<NextPhase, NextCleanliness>(
129 mut self,
130 ) -> Conn<Transport, NextPhase, NextCleanliness> {
131 Conn {
132 transport: self.transport.take(),
133 _state: PhantomData,
134 }
135 }
136
137 pub(crate) fn into_transport(mut self) -> Transport {
143 self.transport
144 .take()
145 .expect("live connection has a transport")
146 }
147
148 pub(crate) fn map_transport<Next>(
154 mut self,
155 map: impl FnOnce(Transport) -> Next,
156 ) -> Conn<Next, Phase, Cleanliness> {
157 Conn {
158 transport: Some(map(self
159 .transport
160 .take()
161 .expect("live connection has a transport"))),
162 _state: PhantomData,
163 }
164 }
165
166 pub(crate) const fn transport(&self) -> &Transport {
167 match &self.transport {
168 Some(transport) => transport,
169 None => panic!("connection transport has already moved"),
170 }
171 }
172
173 pub(crate) const fn transport_mut(&mut self) -> &mut Transport {
174 match &mut self.transport {
175 Some(transport) => transport,
176 None => panic!("connection transport has already moved"),
177 }
178 }
179}
180
181impl<Transport> Conn<Transport, pre_startup::PreStartup, Pristine> {
182 pub(crate) const fn new(transport: Transport) -> Self {
184 Self {
185 transport: Some(transport),
186 _state: PhantomData,
187 }
188 }
189}
190
191#[cfg(debug_assertions)]
192impl<Transport, Phase, Cleanliness> Drop for Conn<Transport, Phase, Cleanliness> {
193 fn drop(&mut self) {
194 assert!(
195 self.transport.is_none() || std::thread::panicking(),
196 "live PostgreSQL connection dropped before a terminal transition; call into_transport() to abort deliberately"
197 );
198 }
199}
200
201#[derive(Debug)]
203pub(crate) enum Pristine {}
204
205#[derive(Debug)]
207pub(crate) enum Dirty {}