Nushell plugin for interacting with D-Bus
1use nu_plugin::{EngineInterface, EvaluatedCall, SimplePluginCommand};
2use nu_protocol::{Example, LabeledError, Signature, SyntaxShape, Type, Value};
3
4use crate::{DbusSignatureUtilExt, client::DbusClient, config::DbusClientConfig};
5
6pub struct Introspect;
7
8impl SimplePluginCommand for Introspect {
9 type Plugin = crate::NuPluginDbus;
10
11 fn name(&self) -> &str {
12 "dbus introspect"
13 }
14
15 fn signature(&self) -> Signature {
16 Signature::build(self.name())
17 .dbus_command()
18 .accepts_dbus_client_options()
19 .accepts_timeout()
20 .input_output_type(Type::Nothing, Type::Record([].into()))
21 .required_named(
22 "dest",
23 SyntaxShape::String,
24 "The name of the connection that owns the object",
25 None,
26 )
27 .required(
28 "object",
29 SyntaxShape::String,
30 "The path to the object to introspect",
31 )
32 }
33
34 fn description(&self) -> &str {
35 "Introspect a D-Bus object"
36 }
37
38 fn extra_description(&self) -> &str {
39 "Returns information about available nodes, interfaces, methods, \
40 signals, and properties on the given object path"
41 }
42
43 fn search_terms(&self) -> Vec<&str> {
44 vec!["dbus", "help", "method"]
45 }
46
47 fn examples(&self) -> Vec<Example<'_>> {
48 vec![
49 Example {
50 example: "dbus introspect --dest=org.mpris.MediaPlayer2.spotify \
51 /org/mpris/MediaPlayer2 | explore",
52 description: "Look at the MPRIS2 interfaces exposed by Spotify",
53 result: None,
54 },
55 Example {
56 example: "dbus introspect --dest=org.kde.plasmashell \
57 /org/kde/osdService | get interfaces | \
58 where name == org.kde.osdService | get 0.methods",
59 description: "Get methods exposed by KDE Plasma's on-screen display \
60 service",
61 result: None,
62 },
63 Example {
64 example: "dbus introspect --dest=org.kde.KWin / | get children | \
65 select name",
66 description: "List objects exposed by KWin",
67 result: None,
68 },
69 ]
70 }
71
72 fn run(
73 &self,
74 _plugin: &Self::Plugin,
75 _engine: &EngineInterface,
76 call: &EvaluatedCall,
77 _input: &Value,
78 ) -> Result<Value, LabeledError> {
79 let config = DbusClientConfig::try_from(call)?;
80 let dbus = DbusClient::new(config)?;
81 let node = dbus.introspect(&call.get_flag("dest")?.unwrap(), &call.req(0)?)?;
82 Ok(node.to_value(call.head))
83 }
84}