1pub mod auth;
4pub mod cancel;
5pub mod cleanliness;
6pub mod codec;
7pub mod credentials;
8pub mod demux;
9pub mod erased;
10pub mod grammar;
11pub mod integrations;
12pub mod intermediary;
13pub mod pre_startup;
14pub mod replication;
15pub mod resources;
16pub mod scram;
17pub mod server_auth;
18pub mod server_session;
19pub mod session;
20pub mod startup;
21pub mod tls;
22pub mod transport;
23
24use std::marker::PhantomData;
25
26#[must_use = "dropping a connection abandons the PostgreSQL session"]
28#[derive(Debug)]
29pub struct Conn<Transport, Phase, Cleanliness = Pristine> {
30 transport: Option<Transport>,
31 _state: PhantomData<(Phase, Cleanliness)>,
32}
33
34impl<Transport, Phase, Cleanliness> Conn<Transport, Phase, Cleanliness> {
35 pub(crate) fn transition<NextPhase, NextCleanliness>(
36 mut self,
37 ) -> Conn<Transport, NextPhase, NextCleanliness> {
38 Conn {
39 transport: self.transport.take(),
40 _state: PhantomData,
41 }
42 }
43
44 pub fn into_transport(mut self) -> Transport {
50 self.transport
51 .take()
52 .expect("live connection has a transport")
53 }
54
55 pub fn map_transport<Next>(
61 mut self,
62 map: impl FnOnce(Transport) -> Next,
63 ) -> Conn<Next, Phase, Cleanliness> {
64 Conn {
65 transport: Some(map(self
66 .transport
67 .take()
68 .expect("live connection has a transport"))),
69 _state: PhantomData,
70 }
71 }
72
73 pub(crate) const fn transport(&self) -> &Transport {
74 match &self.transport {
75 Some(transport) => transport,
76 None => panic!("connection transport has already moved"),
77 }
78 }
79
80 pub(crate) const fn transport_mut(&mut self) -> &mut Transport {
81 match &mut self.transport {
82 Some(transport) => transport,
83 None => panic!("connection transport has already moved"),
84 }
85 }
86}
87
88impl<Transport> Conn<Transport, pre_startup::PreStartup, Pristine> {
89 pub const fn new(transport: Transport) -> Self {
91 Self {
92 transport: Some(transport),
93 _state: PhantomData,
94 }
95 }
96}
97
98#[cfg(debug_assertions)]
99impl<Transport, Phase, Cleanliness> Drop for Conn<Transport, Phase, Cleanliness> {
100 fn drop(&mut self) {
101 assert!(
102 self.transport.is_none() || std::thread::panicking(),
103 "live PostgreSQL connection dropped before a terminal transition; call into_transport() to abort deliberately"
104 );
105 }
106}
107
108#[derive(Debug)]
110pub enum Pristine {}
111
112#[derive(Debug)]
114pub enum Dirty {}