Skip to content

Commit dc0bbe7

Browse files
committed
Added with_entry combinator for JoinMapLane.
1 parent 9ac881e commit dc0bbe7

File tree

3 files changed

+123
-4
lines changed

3 files changed

+123
-4
lines changed

server/swimos_agent/src/lanes/join/map/mod.rs

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::{
1717
borrow::Borrow,
1818
cell::RefCell,
1919
collections::{hash_map::Entry, BTreeSet, HashMap, HashSet},
20-
hash::Hash,
20+
hash::Hash, marker::PhantomData,
2121
};
2222

2323
use bytes::BytesMut;
@@ -32,7 +32,7 @@ use crate::{
3232
event_handler::{
3333
ActionContext, EventHandler, EventHandlerError, HandlerAction, Modification, StepResult,
3434
},
35-
item::{AgentItem, MapItem, MapLikeItem},
35+
item::{AgentItem, InspectableMapLikeItem, MapItem, MapLikeItem},
3636
lanes::{
3737
join_map::default_lifecycle::DefaultJoinMapLifecycle, map::MapLaneEvent, LaneItem, MapLane,
3838
},
@@ -666,6 +666,51 @@ where
666666
}
667667
}
668668

669+
pub struct JoinMapLaneWithEntry<C, L, K, V, F, B: ?Sized> {
670+
projection: for<'a> fn(&'a C) -> &'a JoinMapLane<L, K, V>,
671+
key: K,
672+
f: Option<F>,
673+
_type: PhantomData<fn(&B)>,
674+
}
675+
676+
impl<C, L, K, V, F, B: ?Sized> JoinMapLaneWithEntry<C, L, K, V, F, B> {
677+
678+
pub fn new(projection: for<'a> fn(&'a C) -> &'a JoinMapLane<L, K, V>,
679+
key: K, f: F) -> Self {
680+
JoinMapLaneWithEntry {
681+
projection,
682+
key,
683+
f: Some(f),
684+
_type: PhantomData,
685+
}
686+
}
687+
}
688+
689+
impl<'a, C, L, K, V, F, B, U> HandlerAction<C> for JoinMapLaneWithEntry<C, L, K, V, F, B>
690+
where
691+
K: Eq + Hash + 'static,
692+
C: 'a,
693+
B: ?Sized + 'static,
694+
V: Borrow<B>,
695+
F: FnOnce(Option<&B>) -> U + Send + 'a,
696+
{
697+
type Completion = U;
698+
699+
fn step(
700+
&mut self,
701+
_action_context: &mut ActionContext<C>,
702+
_meta: AgentMetadata,
703+
context: &C,
704+
) -> StepResult<Self::Completion> {
705+
if let Some(f) = self.f.take() {
706+
let item = (self.projection)(context);
707+
StepResult::done(item.inner.with_entry(&self.key, f))
708+
} else {
709+
StepResult::after_done()
710+
}
711+
}
712+
}
713+
669714
impl<L, K, V> MapLikeItem<K, V> for JoinMapLane<L, K, V>
670715
where
671716
L: Send + 'static,
@@ -688,3 +733,32 @@ where
688733
JoinMapLaneGetMap::new(projection)
689734
}
690735
}
736+
737+
impl<L, K, V> InspectableMapLikeItem<K, V> for JoinMapLane<L, K, V>
738+
where
739+
L: Send + 'static,
740+
K: Clone + Eq + Hash + Send + 'static,
741+
V: Send + 'static,
742+
{
743+
type WithEntryHandler<'a, C, F, B, U> = JoinMapLaneWithEntry<C, L, K, V, F, B>
744+
where
745+
Self: 'static,
746+
C: 'a,
747+
B: ?Sized + 'static,
748+
V: Borrow<B>,
749+
F: FnOnce(Option<&B>) -> U + Send + 'a;
750+
751+
fn with_entry_handler<'a, C, F, B, U>(
752+
projection: fn(&C) -> &Self,
753+
key: K,
754+
f: F,
755+
) -> Self::WithEntryHandler<'a, C, F, B, U>
756+
where
757+
Self: 'static,
758+
C: 'a,
759+
B: ?Sized + 'static,
760+
V: Borrow<B>,
761+
F: FnOnce(Option<&B>) -> U + Send + 'a {
762+
JoinMapLaneWithEntry::new(projection, key, f)
763+
}
764+
}

server/swimos_agent/src/lanes/join/map/tests.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::item::AgentItem;
3131
use crate::lanes::join::test_util::{TestDlContextInner, TestDownlinkContext};
3232
use crate::lanes::join_map::default_lifecycle::DefaultJoinMapLifecycle;
3333
use crate::lanes::join_map::{
34-
AddDownlinkAction, JoinMapAddDownlink, JoinMapLaneGet, JoinMapLaneGetMap,
34+
AddDownlinkAction, JoinMapAddDownlink, JoinMapLaneGet, JoinMapLaneGetMap, JoinMapLaneWithEntry,
3535
};
3636
use crate::test_context::{dummy_context, run_event_handlers, run_with_futures};
3737
use crate::{event_handler::StepResult, item::MapItem, meta::AgentMetadata};
@@ -324,3 +324,49 @@ async fn open_downlink_from_registered() {
324324

325325
assert_eq!(count.load(Ordering::Relaxed), 1);
326326
}
327+
328+
#[test]
329+
fn join_map_lane_with_entry_event_handler() {
330+
let uri = make_uri();
331+
let route_params = HashMap::new();
332+
let meta = make_meta(&uri, &route_params);
333+
let agent = TestAgent::with_init();
334+
335+
let mut handler = JoinMapLaneWithEntry::new(TestAgent::LANE, K1, |v: Option<&str>| v.map(str::to_owned));
336+
337+
let result = handler.step(
338+
&mut dummy_context(&mut HashMap::new(), &mut BytesMut::new()),
339+
meta,
340+
&agent,
341+
);
342+
check_result(result, false, false, Some(Some(V1.to_string())));
343+
344+
let result = handler.step(
345+
&mut dummy_context(&mut HashMap::new(), &mut BytesMut::new()),
346+
meta,
347+
&agent,
348+
);
349+
assert!(matches!(
350+
result,
351+
StepResult::Fail(EventHandlerError::SteppedAfterComplete)
352+
));
353+
354+
let mut handler = JoinMapLaneWithEntry::new(TestAgent::LANE, ABSENT, |v: Option<&str>| v.map(str::to_owned));
355+
356+
let result = handler.step(
357+
&mut dummy_context(&mut HashMap::new(), &mut BytesMut::new()),
358+
meta,
359+
&agent,
360+
);
361+
check_result(result, false, false, Some(None));
362+
363+
let result = handler.step(
364+
&mut dummy_context(&mut HashMap::new(), &mut BytesMut::new()),
365+
meta,
366+
&agent,
367+
);
368+
assert!(matches!(
369+
result,
370+
StepResult::Fail(EventHandlerError::SteppedAfterComplete)
371+
));
372+
}

server/swimos_agent/src/lanes/join/value/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,6 @@ impl<C, K, V> JoinValueAddDownlink<C, K, V> {
428428
}
429429
}
430430

431-
432431
pub struct JoinValueLaneWithEntry<C, K, V, F, B: ?Sized> {
433432
projection: for<'a> fn(&'a C) -> &'a JoinValueLane<K, V>,
434433
key: K,

0 commit comments

Comments
 (0)