Skip to content

Commit ba059e6

Browse files
committed
Respond to Mazdak's review
1 parent e1934ed commit ba059e6

2 files changed

Lines changed: 98 additions & 78 deletions

File tree

crates/codegen/src/rust.rs

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -343,26 +343,11 @@ pub(super) fn parse_table_update(
343343

344344
let callback_id = reducer_callback_id_name(&reducer.name);
345345

346-
// The reducer arguments as `ident: ty, ident: ty, ident: ty,`,
347-
// like an argument list.
348-
let mut arglist = String::new();
349-
write_arglist_no_delimiters(module, &mut arglist, &reducer.params_for_generate.elements, None).unwrap();
350-
351-
// The reducer argument types as `&ty, &ty, &ty`,
352-
// for use as the params in a `FnMut` closure type.
353-
let mut arg_types_ref_list = String::new();
354-
// The reducer argument names as `ident, ident, ident`,
355-
// for passing to function call and struct literal expressions.
356-
let mut arg_names_list = String::new();
357-
for (arg_ident, arg_ty) in &reducer.params_for_generate.elements[..] {
358-
arg_types_ref_list += "&";
359-
write_type(module, &mut arg_types_ref_list, arg_ty).unwrap();
360-
arg_types_ref_list += ", ";
361-
362-
let arg_name = arg_ident.deref().to_case(Case::Snake);
363-
arg_names_list += &arg_name;
364-
arg_names_list += ", ";
365-
}
346+
let FormattedArglist {
347+
arglist_no_delimiters,
348+
arg_type_refs,
349+
arg_names,
350+
} = FormattedArglist::for_arguments(module, &reducer.params_for_generate.elements);
366351

367352
write!(out, "impl From<{args_type}> for super::Reducer ");
368353
out.delimited_block(
@@ -417,41 +402,41 @@ pub trait {func_name} {{
417402
/// This method returns immediately, and errors only if we are unable to send the request.
418403
/// The reducer will run asynchronously in the future,
419404
/// and its status can be observed by listening for [`Self::on_{func_name}`] callbacks.
420-
fn {func_name}(&self, {arglist}) -> __sdk::Result<()>;
405+
fn {func_name}(&self, {arglist_no_delimiters}) -> __sdk::Result<()>;
421406
/// Register a callback to run whenever we are notified of an invocation of the reducer `{reducer_name}`.
422407
///
423408
/// Callbacks should inspect the [`__sdk::ReducerEvent`] contained in the [`super::ReducerEventContext`]
424409
/// to determine the reducer's status.
425410
///
426411
/// The returned [`{callback_id}`] can be passed to [`Self::remove_on_{func_name}`]
427412
/// to cancel the callback.
428-
fn on_{func_name}(&self, callback: impl FnMut(&super::ReducerEventContext, {arg_types_ref_list}) + Send + 'static) -> {callback_id};
413+
fn on_{func_name}(&self, callback: impl FnMut(&super::ReducerEventContext, {arg_type_refs}) + Send + 'static) -> {callback_id};
429414
/// Cancel a callback previously registered by [`Self::on_{func_name}`],
430415
/// causing it not to run in the future.
431416
fn remove_on_{func_name}(&self, callback: {callback_id});
432417
}}
433418
434419
impl {func_name} for super::RemoteReducers {{
435-
fn {func_name}(&self, {arglist}) -> __sdk::Result<()> {{
436-
self.imp.call_reducer({reducer_name:?}, {args_type} {{ {arg_names_list} }})
420+
fn {func_name}(&self, {arglist_no_delimiters}) -> __sdk::Result<()> {{
421+
self.imp.call_reducer({reducer_name:?}, {args_type} {{ {arg_names} }})
437422
}}
438423
fn on_{func_name}(
439424
&self,
440-
mut callback: impl FnMut(&super::ReducerEventContext, {arg_types_ref_list}) + Send + 'static,
425+
mut callback: impl FnMut(&super::ReducerEventContext, {arg_type_refs}) + Send + 'static,
441426
) -> {callback_id} {{
442427
{callback_id}(self.imp.on_reducer(
443428
{reducer_name:?},
444429
Box::new(move |ctx: &super::ReducerEventContext| {{
445430
let super::ReducerEventContext {{
446431
event: __sdk::ReducerEvent {{
447432
reducer: super::Reducer::{enum_variant_name} {{
448-
{arg_names_list}
433+
{arg_names}
449434
}},
450435
..
451436
}},
452437
..
453438
}} = ctx else {{ unreachable!() }};
454-
callback(ctx, {arg_names_list})
439+
callback(ctx, {arg_names})
455440
}}),
456441
))
457442
}}
@@ -524,26 +509,11 @@ impl {set_reducer_flags_trait} for super::SetReducerFlags {{
524509

525510
out.newline();
526511

527-
// The arguments as `ident: ty, ident: ty, ident: ty,`,
528-
// like an argument list.
529-
let mut arglist = String::new();
530-
write_arglist_no_delimiters(module, &mut arglist, &procedure.params_for_generate.elements, None).unwrap();
531-
532-
// The argument types as `&ty, &ty, &ty`,
533-
// for use as the params in a `FnMut` closure type.
534-
let mut arg_types_ref_list = String::new();
535-
// The argument names as `ident, ident, ident`,
536-
// for passing to function call and struct literal expressions.
537-
let mut arg_names_list = String::new();
538-
for (arg_ident, arg_ty) in &procedure.params_for_generate.elements[..] {
539-
arg_types_ref_list += "&";
540-
write_type(module, &mut arg_types_ref_list, arg_ty).unwrap();
541-
arg_types_ref_list += ", ";
542-
543-
let arg_name = arg_ident.deref().to_case(Case::Snake);
544-
arg_names_list += &arg_name;
545-
arg_names_list += ", ";
546-
}
512+
let FormattedArglist {
513+
arglist_no_delimiters,
514+
arg_names,
515+
..
516+
} = FormattedArglist::for_arguments(module, &procedure.params_for_generate.elements);
547517

548518
writeln!(
549519
out,
@@ -557,26 +527,26 @@ impl __sdk::InModule for {args_type} {{
557527
///
558528
/// Implemented for [`super::RemoteProcedures`].
559529
pub trait {func_name} {{
560-
fn {func_name}(&self, {arglist}) {{
561-
self.{func_name_with_callback}({arg_names_list} |_, _| {{}});
530+
fn {func_name}(&self, {arglist_no_delimiters}) {{
531+
self.{func_name_with_callback}({arg_names} |_, _| {{}});
562532
}}
563533
564534
fn {func_name_with_callback}(
565535
&self,
566-
{arglist}
536+
{arglist_no_delimiters}
567537
__callback: impl FnOnce(&super::ProcedureEventContext, Result<{res_ty_name}, __sdk::InternalError>) + Send + 'static,
568538
);
569539
}}
570540
571541
impl {func_name} for super::RemoteProcedures {{
572542
fn {func_name_with_callback}(
573543
&self,
574-
{arglist}
544+
{arglist_no_delimiters}
575545
__callback: impl FnOnce(&super::ProcedureEventContext, Result<{res_ty_name}, __sdk::InternalError>) + Send + 'static,
576546
) {{
577547
self.imp.invoke_procedure_with_callback::<_, {res_ty_name}>(
578548
{procedure_name:?},
579-
{args_type} {{ {arg_names_list} }},
549+
{args_type} {{ {arg_names} }},
580550
__callback,
581551
);
582552
}}
@@ -691,6 +661,51 @@ pub fn type_name(module: &ModuleDef, ty: &AlgebraicTypeUse) -> String {
691661
s
692662
}
693663

664+
/// Arguments to a reducer or procedure pretty-printed in various ways that are convenient to compute together.
665+
struct FormattedArglist {
666+
/// The arguments as `ident: ty, ident: ty, ident: ty,`,
667+
/// like an argument list.
668+
///
669+
/// Always carries a trailing comma, unless it's zero elements.
670+
arglist_no_delimiters: String,
671+
/// The argument types as `&ty, &ty, &ty,`,
672+
/// for use as the params in a function/closure type.
673+
///
674+
/// Always carries a trailing comma, unless it's zero elements.
675+
arg_type_refs: String,
676+
/// The argument names as `ident, ident, ident,`,
677+
/// for passing to function call and struct literal expressions.
678+
///
679+
/// Always carries a trailing comma, unless it's zero elements.
680+
arg_names: String,
681+
}
682+
683+
impl FormattedArglist {
684+
fn for_arguments(module: &ModuleDef, params: &[(Identifier, AlgebraicTypeUse)]) -> Self {
685+
let mut arglist_no_delimiters = String::new();
686+
write_arglist_no_delimiters(module, &mut arglist_no_delimiters, params, None)
687+
.expect("Writing to a String failed... huh?");
688+
689+
let mut arg_type_refs = String::new();
690+
let mut arg_names = String::new();
691+
for (arg_ident, arg_ty) in params {
692+
arg_type_refs += "&";
693+
write_type(module, &mut arg_type_refs, arg_ty).expect("Writing to a String failed... huh?");
694+
arg_type_refs += ", ";
695+
696+
let arg_name = arg_ident.deref().to_case(Case::Snake);
697+
arg_names += &arg_name;
698+
arg_names += ", ";
699+
}
700+
701+
Self {
702+
arglist_no_delimiters,
703+
arg_type_refs,
704+
arg_names,
705+
}
706+
}
707+
}
708+
694709
const ALLOW_LINTS: &str = "#![allow(unused, clippy::all)]";
695710

696711
const SPACETIMEDB_IMPORTS: &[&str] = &[

sdks/rust/src/db_connection.rs

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ impl<M: SpacetimeModule> DbContextImpl<M> {
370370
let msg = ws::ClientMessage::CallReducer(ws::CallReducer {
371371
reducer: reducer.into(),
372372
args: args_bsatn.into(),
373+
// We could call `next_request_id` to get a unique ID to include here,
374+
// but we don't have any use for such an ID, so we don't bother.
373375
request_id: 0,
374376
flags,
375377
});
@@ -382,6 +384,35 @@ impl<M: SpacetimeModule> DbContextImpl<M> {
382384
.expect("Unable to send reducer call message: WS sender loop has dropped its recv channel");
383385
}
384386

387+
// Invoke a procedure: stash its callback, then send the `CallProcedure` WS message.
388+
PendingMutation::InvokeProcedureWithCallback {
389+
procedure,
390+
args,
391+
callback,
392+
} => {
393+
// We need to include a request_id in the message so that we can find the callback once it completes.
394+
let request_id = next_request_id();
395+
self.inner
396+
.lock()
397+
.unwrap()
398+
.procedure_callbacks
399+
.insert(request_id, callback);
400+
401+
let msg = ws::ClientMessage::CallProcedure(ws::CallProcedure {
402+
procedure: procedure.into(),
403+
args: args.into(),
404+
request_id,
405+
flags: ws::CallProcedureFlags::Default,
406+
});
407+
self.send_chan
408+
.lock()
409+
.unwrap()
410+
.as_mut()
411+
.ok_or(crate::Error::Disconnected)?
412+
.unbounded_send(msg)
413+
.expect("Unable to send procedure call message: WS sender loop has dropped its recv channel");
414+
}
415+
385416
// Disconnect: close the connection.
386417
PendingMutation::Disconnect => {
387418
// Set `send_chan` to `None`, since `Self::is_active` checks that.
@@ -480,32 +511,6 @@ impl<M: SpacetimeModule> DbContextImpl<M> {
480511
.call_reducer_flags
481512
.set_flags(reducer_name, flags);
482513
}
483-
PendingMutation::InvokeProcedureWithCallback {
484-
procedure,
485-
args,
486-
callback,
487-
} => {
488-
let request_id = next_request_id();
489-
self.inner
490-
.lock()
491-
.unwrap()
492-
.procedure_callbacks
493-
.insert(request_id, callback);
494-
495-
let msg = ws::ClientMessage::CallProcedure(ws::CallProcedure {
496-
procedure: procedure.into(),
497-
args: args.into(),
498-
request_id,
499-
flags: ws::CallProcedureFlags::Default,
500-
});
501-
self.send_chan
502-
.lock()
503-
.unwrap()
504-
.as_mut()
505-
.ok_or(crate::Error::Disconnected)?
506-
.unbounded_send(msg)
507-
.expect("Unable to send procedure call message: WS sender loop has dropped its recv channel");
508-
}
509514
};
510515
Ok(())
511516
}

0 commit comments

Comments
 (0)