From b1eedd3b64e497a645fd1bcdbeec9159a185e505 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Fri, 13 Feb 2026 08:49:58 +0000 Subject: [PATCH] protocol/service: introduce Responder type Introduce a `Responder` type that wraps a `crossbeam_channel::Sender>`. It provides a standard constructor and three sending methods: one for a `Result`, one for an `Ok` value, and one for an `Err` value. --- .../radicle-protocol/src/service/command.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/radicle-protocol/src/service/command.rs b/crates/radicle-protocol/src/service/command.rs index b1f12994..3110cee8 100644 --- a/crates/radicle-protocol/src/service/command.rs +++ b/crates/radicle-protocol/src/service/command.rs @@ -1,5 +1,7 @@ use std::{collections::HashSet, fmt, sync::Arc, time}; +use crossbeam_channel::Receiver; +use crossbeam_channel::SendError; use crossbeam_channel::Sender; use radicle::crypto::PublicKey; use radicle::node::policy::Scope; @@ -20,6 +22,45 @@ pub type QueryState = dyn Fn(&dyn ServiceState) -> Result<()> + Send + Sync; /// It is a type synonym for a [`std::result::Result`] pub type Result = std::result::Result; +/// A [`Responder`] returns results after processing a service [`Command`]. +/// +/// To construct a [`Responder`], use [`Responder::new`], which also returns its +/// corresponding [`Receiver`]. +/// +/// To send results, use either: +/// - [`Responder::send`] +/// - [`Responder::ok`] +/// - [`Responder::err`] +pub struct Responder { + channel: Sender>, +} + +impl Responder { + /// Construct a new [`Responder`] and its corresponding [`Receiver`]. + pub fn new() -> (Self, Receiver>) { + let (sender, receiver) = crossbeam_channel::bounded(1); + (Self { channel: sender }, receiver) + } + + /// Send a [`Result`] to the receiver. + pub fn send(&self, result: Result) -> std::result::Result<(), SendError>> { + self.channel.send(result) + } + + /// Send a [`Result::Ok`] to the receiver. + pub fn ok(&self, value: T) -> std::result::Result<(), SendError>> { + self.send(Ok(value)) + } + + /// Send a [`Result::Err`] to the receiver. + pub fn err(&self, error: E) -> std::result::Result<(), SendError>> + where + E: std::error::Error + Send + Sync + 'static, + { + self.send(Err(Error::other(error))) + } +} + /// Commands sent to the service by the operator. pub enum Command { /// Announce repository references for given repository and namespaces to peers.