blob: a8578ff7582c10cc458d7009c466905ae26c6c44 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
crate::table::*,
anyhow::Error,
fidl_fuchsia_inspect_deprecated::{self as fidl_inspect, InspectRequest, InspectRequestStream},
fuchsia_async as fasync,
futures::{TryFutureExt, TryStreamExt},
};
pub fn spawn_inspect_server(mut stream: InspectRequestStream, node: NodeObject) {
fasync::Task::spawn(
async move {
while let Some(req) = stream.try_next().await? {
match req {
InspectRequest::ReadData { responder } => {
let metrics = get_metrics(&node);
let properties = get_properties(&node);
let mut object = fidl_inspect::Object {
name: node.get_node_name(),
properties,
metrics,
};
responder.send(&mut object)?;
}
InspectRequest::ListChildren { responder } => {
let mut names = get_children_names(&node);
names.sort();
responder.send(&mut names.into_iter())?;
}
InspectRequest::OpenChild { child_name, child_channel, responder } => {
let stream = child_channel.into_stream()?;
let ok = match &node {
NodeObject::Root(table) => {
spawn_inspect_server(stream, NodeObject::Table(table.clone()));
true
}
NodeObject::Row(row) => {
match row.cells.iter().find(|c| c.node_name == child_name) {
Some(child) => {
spawn_inspect_server(
stream,
NodeObject::Cell(child.clone()),
);
true
}
None => false,
}
}
NodeObject::Table(table) => {
match table.rows.iter().find(|c| c.node_name == child_name) {
Some(child) => {
spawn_inspect_server(
stream,
NodeObject::Row(child.clone()),
);
true
}
None => false,
}
}
_ => false,
};
responder.send(ok)?;
}
}
}
Ok(())
}
.unwrap_or_else(|e: Error| eprintln!("error running inspect server: {:?}", e)),
)
.detach();
}
fn get_children_names(node: &NodeObject) -> Vec<&str> {
match node {
NodeObject::Table(table) => {
table.rows.iter().map(|row| row.node_name.as_ref()).collect::<Vec<&str>>()
}
NodeObject::Row(row) => {
row.cells.iter().map(|cell| cell.node_name.as_ref()).collect::<Vec<&str>>()
}
NodeObject::Root(table) => vec![table.node_name.as_ref()],
_ => vec![],
}
}
fn get_metrics(node: &NodeObject) -> Vec<fidl_inspect::Metric> {
match node {
NodeObject::Cell(cell) => vec![
fidl_inspect::Metric {
key: "double_value".to_string(),
value: fidl_inspect::MetricValue::DoubleValue(cell.double_value),
},
fidl_inspect::Metric {
key: "value".to_string(),
value: fidl_inspect::MetricValue::IntValue(cell.value),
},
],
_ => vec![],
}
}
fn get_properties(node: &NodeObject) -> Vec<fidl_inspect::Property> {
match node {
NodeObject::Cell(cell) => vec![fidl_inspect::Property {
key: "name".to_string(),
value: fidl_inspect::PropertyValue::Str(cell.name.clone()),
}],
NodeObject::Table(table) => vec![
fidl_inspect::Property {
key: "binary_data".to_string(),
value: fidl_inspect::PropertyValue::Bytes(table.binary_data.clone()),
},
fidl_inspect::Property {
key: "object_name".to_string(),
value: fidl_inspect::PropertyValue::Str(table.object_name.clone()),
},
],
_ => vec![],
}
}