agent_client_protocol/jsonrpc/
run.rs1use std::future::Future;
8use std::marker::PhantomData;
9
10use crate::{
11 ConnectionTo,
12 jsonrpc::{ConnectionContext, RawConnectionContext, connection_context},
13 role::Role,
14};
15
16pub trait RunWithConnectionTo<Counterpart: Role>: Send {
24 fn run_with_connection_to(
26 self,
27 cx: ConnectionTo<Counterpart>,
28 ) -> impl Future<Output = Result<(), crate::Error>> + Send;
29}
30
31#[derive(Debug, Default)]
33pub struct NullRun;
34
35impl<Counterpart: Role> RunWithConnectionTo<Counterpart> for NullRun {
36 fn run_with_connection_to(
37 self,
38 _cx: ConnectionTo<Counterpart>,
39 ) -> impl Future<Output = Result<(), crate::Error>> + Send {
40 std::future::ready(Ok(()))
41 }
42}
43
44#[derive(Debug)]
46pub struct ChainRun<A, B> {
47 a: A,
48 b: B,
49}
50
51impl<A, B> ChainRun<A, B> {
52 pub fn new(a: A, b: B) -> Self {
54 Self { a, b }
55 }
56}
57
58impl<Counterpart: Role, A, B> RunWithConnectionTo<Counterpart> for ChainRun<A, B>
59where
60 A: RunWithConnectionTo<Counterpart>,
61 B: RunWithConnectionTo<Counterpart>,
62{
63 async fn run_with_connection_to(
64 self,
65 cx: ConnectionTo<Counterpart>,
66 ) -> Result<(), crate::Error> {
67 let a_fut = Box::pin(self.a.run_with_connection_to(cx.clone()));
69 let b_fut = Box::pin(self.b.run_with_connection_to(cx.clone()));
70 let ((), ()) = futures::future::try_join(a_fut, b_fut).await?;
71 Ok(())
72 }
73}
74
75pub struct SpawnedRun<F, Context = RawConnectionContext> {
77 task_fn: F,
78 location: &'static std::panic::Location<'static>,
79 context: PhantomData<fn() -> Context>,
80}
81
82impl<F, Context> SpawnedRun<F, Context> {
83 pub fn new(location: &'static std::panic::Location<'static>, task_fn: F) -> Self {
85 Self {
86 task_fn,
87 location,
88 context: PhantomData,
89 }
90 }
91}
92
93impl<Counterpart, F, Fut, Context> RunWithConnectionTo<Counterpart> for SpawnedRun<F, Context>
94where
95 Counterpart: Role,
96 Context: ConnectionContext,
97 F: FnOnce(Context::Connection<Counterpart>) -> Fut + Send,
98 Fut: Future<Output = Result<(), crate::Error>> + Send,
99{
100 async fn run_with_connection_to(
101 self,
102 connection: ConnectionTo<Counterpart>,
103 ) -> Result<(), crate::Error> {
104 let location = self.location;
105 (self.task_fn)(connection_context::from_raw::<Context, _>(connection))
106 .await
107 .map_err(|err| {
108 let data = err.data.clone();
109 err.data(serde_json::json!({
110 "spawned_at": format!("{}:{}:{}", location.file(), location.line(), location.column()),
111 "data": data,
112 }))
113 })
114 }
115}