-
Notifications
You must be signed in to change notification settings - Fork 13
/
epmd_cli.rs
107 lines (98 loc) · 3.39 KB
/
epmd_cli.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! EPMD client example.
//!
//! # Usage Examples
//!
//! ```bash
//! $ cargo run --example epmd_cli -- --help
//! $ cargo run --example epmd_cli names
//! $ cargo run --example epmd_cli node_info foo
//! ```
use clap::{Parser, Subcommand};
use erl_dist::epmd::{EpmdClient, NodeEntry};
#[derive(Debug, Parser)]
#[clap(name = "epmd_cli")]
struct Args {
#[clap(long, short = 'h', default_value = "127.0.0.1")]
epmd_host: String,
#[clap(long, short = 'p', default_value_t = erl_dist::epmd::DEFAULT_EPMD_PORT)]
epmd_port: u16,
#[clap(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
Names,
Dump,
NodeEntry {
node: String,
},
Kill,
Register {
name: String,
#[clap(long, default_value_t = 3000)]
port: u16,
#[clap(long)]
hidden: bool,
},
}
fn main() -> anyhow::Result<()> {
let args = Args::parse();
smol::block_on(async {
let stream =
smol::net::TcpStream::connect(format!("{}:{}", args.epmd_host, args.epmd_port)).await?;
let client = EpmdClient::new(stream);
match args.command {
Command::Names => {
// 'NAMES_REQ'
let names = client.get_names().await?;
let result = serde_json::json!(names
.into_iter()
.map(|(name, port)| serde_json::json!({"name": name, "port": port}))
.collect::<Vec<_>>());
println!("{}", serde_json::to_string_pretty(&result)?);
}
Command::NodeEntry { node } => {
// 'PORT_PLEASE2_REQ'
if let Some(node) = client.get_node(&node).await? {
let result = serde_json::json!({
"name": node.name,
"port": node.port,
"node_type": format!("{:?} ({})", node.node_type, u8::from(node.node_type)),
"protocol": format!("{:?} ({})", node.protocol, u8::from(node.protocol)),
"highest_version": node.highest_version,
"lowest_version": node.lowest_version,
"extra": node.extra
});
println!("{}", serde_json::to_string_pretty(&result)?);
} else {
anyhow::bail!("No such node: {:?}", node);
}
}
Command::Dump => {
// 'DUMP_REQ'
let result = client.dump().await?;
println!("{}", result);
}
Command::Kill => {
// 'KILL_REQ'
let result = client.kill().await?;
let result = serde_json::json!({ "result": result });
println!("{}", serde_json::to_string_pretty(&result)?);
}
Command::Register { name, port, hidden } => {
// 'ALIVE2_REQ'
let node = if hidden {
NodeEntry::new_hidden(&name, port)
} else {
NodeEntry::new(&name, port)
};
let (_, creation) = client.register(node).await?;
let result = serde_json::json!({
"creation": creation.get()
});
println!("{}", serde_json::to_string_pretty(&result)?);
}
}
Ok(())
})
}