Skip to main content

fastcgi_client/
conn.rs

1// Copyright 2022 jmjoy
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Connection mode markers for [`Client`](crate::Client).
16//!
17//! A [`Client`](crate::Client) is parameterized by a connection mode, which is
18//! a compile time only marker: it selects the value of the `FCGI_KEEP_CONN`
19//! flag sent in the `FCGI_BEGIN_REQUEST` record, and it decides which request
20//! methods are available.
21//!
22//! This crate never creates, closes or otherwise manages sockets; the stream is
23//! owned by the caller. The mode therefore only describes what the client tells
24//! the FastCGI server about connection reuse, and how the client type behaves
25//! afterwards:
26//!
27//! - [`ShortConn`]: the server is free to close the connection once the
28//!   response is complete, so the client can be used for a single request and
29//!   its request methods consume `self`.
30//! - [`KeepAlive`]: the server is asked to keep the connection open, so the
31//!   client stays usable and its request methods take `&mut self`, sending
32//!   requests one after another.
33
34mod sealed {
35    /// Prevents [`Mode`](super::Mode) from being implemented outside of this
36    /// crate.
37    pub trait Sealed {}
38}
39
40/// Marker trait implemented by the connection modes of
41/// [`Client`](crate::Client).
42///
43/// This trait is sealed: [`ShortConn`] and [`KeepAlive`] are its only
44/// implementors and no other type can implement it, which keeps the set of
45/// connection modes closed and allows it to gain new members without breaking
46/// downstream code.
47///
48/// ```compile_fail
49/// use fastcgi_client::conn::Mode;
50///
51/// enum MyMode {}
52///
53/// // error: the trait bound `MyMode: Sealed` is not satisfied
54/// impl Mode for MyMode {
55///     const KEEP_CONN: bool = true;
56/// }
57/// ```
58pub trait Mode: sealed::Sealed {
59    /// Value of the `FCGI_KEEP_CONN` flag sent in the `FCGI_BEGIN_REQUEST`
60    /// record.
61    ///
62    /// When `false`, the FastCGI server closes the connection after responding.
63    const KEEP_CONN: bool;
64}
65
66/// Short connection mode.
67///
68/// The `FCGI_KEEP_CONN` flag is not set, so the FastCGI server closes the
69/// connection after it finished responding. Consequently the request methods of
70/// [`Client<S, ShortConn>`](crate::Client) consume the client, and a new stream
71/// is needed for the next request.
72///
73/// This type is a compile time marker and cannot be instantiated:
74///
75/// ```compile_fail
76/// use fastcgi_client::conn::ShortConn;
77///
78/// // error: expected value, found enum `ShortConn`
79/// let _mode = ShortConn;
80/// ```
81///
82/// A short connection client is consumed by its request methods, so it cannot
83/// be reused:
84///
85/// ```compile_fail
86/// # async fn example() {
87/// use fastcgi_client::{io, Client, Params, Request};
88///
89/// let stream = smol::net::TcpStream::connect(("127.0.0.1", 9000))
90///     .await
91///     .unwrap();
92/// let client = Client::new(stream);
93///
94/// let _ = client
95///     .execute_once(Request::new(Params::default(), io::empty()))
96///     .await;
97///
98/// // error[E0382]: use of moved value: `client`
99/// let _ = client
100///     .execute_once(Request::new(Params::default(), io::empty()))
101///     .await;
102/// # }
103/// ```
104pub enum ShortConn {}
105
106impl sealed::Sealed for ShortConn {}
107
108impl Mode for ShortConn {
109    const KEEP_CONN: bool = false;
110}
111
112/// Keep alive connection mode.
113///
114/// The `FCGI_KEEP_CONN` flag is set, asking the FastCGI server to keep the
115/// connection open after responding. The request methods of
116/// [`Client<S, KeepAlive>`](crate::Client) therefore take `&mut self` and can
117/// be called repeatedly, sending one request at a time over the same stream.
118///
119/// This type is a compile time marker and cannot be instantiated:
120///
121/// ```compile_fail
122/// use fastcgi_client::conn::KeepAlive;
123///
124/// // error: expected value, found enum `KeepAlive`
125/// let _mode = KeepAlive {};
126/// ```
127pub enum KeepAlive {}
128
129impl sealed::Sealed for KeepAlive {}
130
131impl Mode for KeepAlive {
132    const KEEP_CONN: bool = true;
133}