nyquest_interface/blocking/backend.rs
1//! Core blocking client interface traits.
2//!
3//! This module provides the core trait definitions that backend implementations
4//! must implement to provide blocking HTTP functionality.
5//!
6//! Backend developers need to implement the `BlockingBackend` and `BlockingClient` traits,
7//! along with a custom `BlockingResponse` type.
8
9use std::{fmt, io};
10
11use super::Request;
12use crate::client::ClientOptions;
13use crate::Result;
14
15/// Trait for blocking HTTP clients.
16///
17/// Backend implementations must provide a concrete type that implements this trait
18/// to handle blocking HTTP requests.
19pub trait BlockingClient: Clone + Send + Sync + 'static {
20 /// The type of response returned by this client.
21 type Response: BlockingResponse;
22
23 /// Provides a textual description of this client.
24 fn describe(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 write!(f, "BlockingClient")
26 }
27
28 /// Sends an HTTP request and returns the response.
29 fn request(&self, req: Request) -> crate::Result<Self::Response>;
30}
31
32/// Trait for blocking HTTP backend implementations.
33///
34/// This trait represents a backend implementation that can create blocking HTTP clients.
35pub trait BlockingBackend: Send + Sync + 'static {
36 /// The type of client this backend creates.
37 type BlockingClient: BlockingClient;
38
39 /// Creates a new blocking client with the given options.
40 fn create_blocking_client(&self, options: ClientOptions) -> Result<Self::BlockingClient>;
41}
42
43/// Trait for blocking HTTP responses.
44///
45/// This trait provides methods for accessing the data in an HTTP response
46/// and extends io::Read to allow streaming the response body.
47///
48/// ## Response Method Receivers
49///
50/// Note that the `BlockingResponse` trait uses `&mut self` receivers for content reading methods
51/// (`text()`, `bytes()`, etc.) to ensure object safety and dyn compatibility.
52/// This differs from the main nyquest crate which uses consuming `self` receivers.
53///
54/// Backend implementors should design their implementations with the understanding that
55/// these methods may be called only once per response instance, even though the signature allows
56/// multiple calls. The nyquest facade enforces this by consuming the response.
57pub trait BlockingResponse: io::Read + Send + Sync + 'static {
58 /// Provides a textual description of this response.
59 fn describe(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 write!(f, "BlockingResponse")
61 }
62
63 /// Returns the HTTP status code of this response.
64 fn status(&self) -> u16;
65
66 /// Returns the content-length of the response body, if known.
67 fn content_length(&self) -> Option<u64>;
68
69 /// Gets all values for the specified header.
70 fn get_header(&self, header: &str) -> crate::Result<Vec<String>>;
71
72 /// Reads the response body as text.
73 fn text(&mut self) -> crate::Result<String>;
74
75 /// Reads the response body as bytes.
76 fn bytes(&mut self) -> crate::Result<Vec<u8>>;
77}