fdf_channel/
test_utils.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Helpers for writing tests involving channels.
6
7use std::cell::Cell;
8use std::sync::mpsc;
9
10/// Implements a cloneable object that will send only one message
11/// on an [`mpsc::Sender`] when its 'last' clone is dropped. It will assert
12/// if an attempt to re-clone an already cloned [`DropSender`] happens,
13/// ensuring that the object is only cloned in a linear path.
14pub struct DropSender<T: Clone>(pub T, Cell<Option<mpsc::Sender<T>>>);
15impl<T: Clone> DropSender<T> {
16    /// When this object is dropped it will send 'val' to the given 'sender'.
17    pub fn new(val: T, sender: mpsc::Sender<T>) -> Self {
18        Self(val, Cell::new(Some(sender)))
19    }
20}
21impl<T: Clone> Drop for DropSender<T> {
22    fn drop(&mut self) {
23        if let Some(sender) = self.1.get_mut() {
24            println!("dropping a drop sender");
25            sender.send(self.0.clone()).unwrap();
26        }
27    }
28}
29impl<T: Clone> Clone for DropSender<T> {
30    fn clone(&self) -> Self {
31        Self(
32            self.0.clone(),
33            Cell::new(Some(self.1.take().expect("Attempted to re-clone a `DropSender`"))),
34        )
35    }
36}