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}