ndn_app/responder.rs
1//! [`Responder`] — reply builder passed to producer handlers.
2
3use std::sync::Arc;
4
5use bytes::Bytes;
6
7use ndn_packet::lp::encode_lp_nack;
8use ndn_packet::{NackReason, Name};
9
10use crate::AppError;
11use crate::connection::NdnConnection;
12
13/// Reply builder passed to producer handlers in [`Producer::serve`].
14///
15/// A `Responder` is a single-use object: call exactly one of [`respond`],
16/// [`respond_bytes`], or [`nack`] to send a reply. Dropping without calling
17/// a reply method silently discards the Interest.
18///
19/// # Example
20///
21/// ```rust,no_run
22/// # async fn example(mut producer: ndn_app::Producer) -> Result<(), ndn_app::AppError> {
23/// use ndn_packet::encode::DataBuilder;
24///
25/// producer.serve(|interest, responder| async move {
26/// let data = DataBuilder::new((*interest.name).clone(), b"hello").build();
27/// responder.respond_bytes(data).await.ok();
28/// }).await
29/// # }
30/// ```
31pub struct Responder {
32 conn: Arc<NdnConnection>,
33 /// Original Interest wire bytes, needed to encode a valid Nack reply.
34 interest_wire: Bytes,
35}
36
37impl Responder {
38 pub(crate) fn new(conn: Arc<NdnConnection>, interest_wire: Bytes) -> Self {
39 Self {
40 conn,
41 interest_wire,
42 }
43 }
44
45 /// Send a raw pre-encoded Data wire packet as the reply.
46 pub async fn respond_bytes(self, wire: Bytes) -> Result<(), AppError> {
47 self.conn.send(wire).await
48 }
49
50 /// Build and send a Data packet with the given name and content.
51 pub async fn respond(self, name: Name, content: impl Into<Bytes>) -> Result<(), AppError> {
52 let data = ndn_packet::encode::DataBuilder::new(name, &content.into()).build();
53 self.conn.send(data).await
54 }
55
56 /// Send a Nack reply for the Interest.
57 ///
58 /// The Nack is encoded as an NDNLPv2 LpPacket containing the original
59 /// Interest wire as the Fragment field, per NDNLPv2 §5.2.
60 pub async fn nack(self, reason: NackReason) -> Result<(), AppError> {
61 let nack_wire = encode_lp_nack(reason, &self.interest_wire);
62 self.conn.send(nack_wire).await
63 }
64}