Skip to main content

driver_manager_types/
bind_result_tracker.rs

1// Copyright 2026 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
5use futures::channel::oneshot;
6use {fidl_fuchsia_driver_development as fdd, fidl_fuchsia_driver_framework as fdf};
7
8pub type NodeBindingInfoResultCompleter = oneshot::Sender<Vec<fdd::NodeBindingInfo>>;
9
10#[derive(Debug)]
11pub struct BindResultTracker {
12    expected_result_count: usize,
13    currently_reported: usize,
14    result_completer: Option<NodeBindingInfoResultCompleter>,
15    results: Vec<fdd::NodeBindingInfo>,
16}
17
18impl BindResultTracker {
19    pub fn new(
20        expected_result_count: usize,
21        result_completer: NodeBindingInfoResultCompleter,
22    ) -> Self {
23        if expected_result_count == 0 {
24            // If the receiver has been dropped, we don't need to do anything.
25            let _ = result_completer.send(vec![]);
26            return Self {
27                expected_result_count,
28                currently_reported: 0,
29                result_completer: None,
30                results: Vec::new(),
31            };
32        }
33        Self {
34            expected_result_count,
35            currently_reported: 0,
36            result_completer: Some(result_completer),
37            results: Vec::new(),
38        }
39    }
40
41    pub fn report_no_bind(&mut self) {
42        self.currently_reported += 1;
43        let current = self.currently_reported;
44        self.complete(current);
45    }
46
47    pub fn report_successful_bind_driver(&mut self, node_name: &str, driver: &str) {
48        self.currently_reported += 1;
49        self.results.push(fdd::NodeBindingInfo {
50            node_name: Some(node_name.to_string()),
51            driver_url: Some(driver.to_string()),
52            ..Default::default()
53        });
54        let current = self.currently_reported;
55        self.complete(current);
56    }
57
58    pub fn report_successful_bind_composite(
59        &mut self,
60        node_name: &str,
61        composite_parents: &[fdf::CompositeParent],
62    ) {
63        self.currently_reported += 1;
64        self.results.push(fdd::NodeBindingInfo {
65            node_name: Some(node_name.to_string()),
66            composite_parents: Some(composite_parents.to_vec()),
67            ..Default::default()
68        });
69        let current = self.currently_reported;
70        self.complete(current);
71    }
72
73    fn complete(&mut self, current: usize) {
74        if current == self.expected_result_count
75            && let Some(completer) = self.result_completer.take()
76        {
77            // If the receiver has been dropped, we don't need to do anything.
78            let _ = completer.send(std::mem::take(&mut self.results));
79        }
80    }
81}