ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/salaryman/trunk/src/main.rs
Revision: 6
Committed: Tue Jun 3 16:48:06 2025 UTC (4 months ago) by yuzu
File size: 2879 byte(s)
Log Message:
boilerplate done

File Contents

# Content
1 use clap::Parser;
2 use serde::{Deserialize, Serialize};
3
4 use tokio::fs::read_to_string;
5 use tokio::fs::write;
6
7 use std::{
8 fs::canonicalize,
9 io::Read,
10 net::{IpAddr, Ipv4Addr, Ipv6Addr},
11 path::PathBuf,
12 process::{Child, Command, Stdio},
13 };
14
15 #[derive(Parser)]
16 #[command(version, about, long_about = None)]
17 struct Args {
18 #[arg(short, long, value_name = "FILE")]
19 config: Option<PathBuf>,
20 #[arg(short, long, value_name = "ADDR")]
21 address: Option<IpAddr>,
22 #[arg(short, long, value_name = "PORT")]
23 port: Option<u16>,
24 }
25
26 #[derive(Serialize, Deserialize, Debug)]
27 struct Service {
28 name: String,
29 command: String,
30 args: Option<String>,
31 directory: Option<PathBuf>,
32 autostart: bool,
33 }
34 impl Service {
35 fn new() -> Self {
36 Self {
37 name: String::new(),
38 command: String::new(),
39 args: None,
40 directory: None,
41 autostart: false,
42 }
43 }
44 }
45
46 #[derive(Serialize, Deserialize, Debug)]
47 struct Config {
48 address: Option<IpAddr>,
49 port: Option<u16>,
50 service: Vec<Service>,
51 }
52 impl Config {
53 fn new() -> Self {
54 Self {
55 address: None,
56 port: None,
57 service: Vec::new(),
58 }
59 }
60 }
61
62 fn exec(
63 image: &str,
64 args: Vec<&str>,
65 dir: Option<PathBuf>,
66 ) -> Result<Child, Box<dyn std::error::Error>> {
67 if let Some(cwd) = dir {
68 let child = Command::new(image)
69 .args(args)
70 .current_dir(canonicalize(cwd)?)
71 .stdin(Stdio::piped())
72 .stdout(Stdio::piped())
73 .stderr(Stdio::piped())
74 .spawn()?;
75 Ok(child)
76 } else {
77 let child = Command::new(image)
78 .args(args)
79 .stdin(Stdio::piped())
80 .stdout(Stdio::piped())
81 .stderr(Stdio::piped())
82 .spawn()?;
83 Ok(child)
84 }
85 }
86
87 async fn load_config(file: PathBuf) -> Config {
88 let s: String = match read_to_string(file).await {
89 Ok(s) => s,
90 Err(_) => String::new(),
91 };
92 match toml::from_str(s.as_str()) {
93 Ok(c) => c,
94 Err(_) => Config::new(),
95 }
96 }
97
98 #[tokio::main]
99 async fn main() -> Result<(), Box<dyn std::error::Error>> {
100 let args = Args::parse();
101 let conf: Config = load_config(PathBuf::from("salaryman.toml")).await;
102
103 println!("{conf:?}");
104
105 /*
106 let mut child = exec("java", vec!["-jar", "minecraft_server.jar"], None)?;
107 std::thread::sleep(std::time::Duration::from_secs(60));
108 let mut buf: [u8; 512] = [0; 512];
109 let mut ebuf: [u8; 512] = [0; 512];
110 child.stdout.as_mut().unwrap().read(&mut buf[..])?;
111 child.stderr.as_mut().unwrap().read(&mut ebuf[..])?;
112 println!("{}", String::from_utf8_lossy(&buf));
113 println!("{}", String::from_utf8_lossy(&ebuf));
114 child.kill()?;
115 */
116 Ok(())
117 }