tangled
alpha
login
or
join now
vielle.dev
/
wol
1
fork
atom
[WIP] A simple wake-on-lan service
1
fork
atom
overview
issues
pulls
pipelines
expose config as a server endpoint
vielle.dev
3 weeks ago
13b4c7a6
22b5e3f8
verified
This commit was signed with the committer's
known signature
.
vielle.dev
SSH Key Fingerprint:
SHA256:EoUuRRBFQKUfYh74C568g83i9g4fVi5OTtOENMSfa+0=
+38
-13
4 changed files
expand all
collapse all
unified
split
src
config.rs
mac.rs
main.rs
server.rs
+7
-4
src/config.rs
···
1
1
-
use serde::Deserialize;
1
1
+
use serde::{Deserialize, Serialize};
2
2
use std::{collections::HashMap, fs::File, io::Read, path::PathBuf};
3
3
use thiserror::Error;
4
4
5
5
-
#[derive(Deserialize, Debug, Clone)]
5
5
+
#[derive(Deserialize, Serialize, Debug, Clone)]
6
6
pub struct Config {
7
7
#[serde(default = "default_binding")]
8
8
pub binding: String,
9
9
pub targets: HashMap<String, Target>,
10
10
}
11
11
12
12
-
#[derive(Deserialize, Debug, Clone)]
12
12
+
#[derive(Deserialize, Serialize, Debug, Clone)]
13
13
pub struct Target {
14
14
-
#[serde(deserialize_with = "crate::mac::deserialize_mac")]
14
14
+
#[serde(
15
15
+
deserialize_with = "crate::mac::deserialize_mac",
16
16
+
serialize_with = "crate::mac::serialize_mac"
17
17
+
)]
15
18
pub mac: crate::mac::MacAddress,
16
19
pub ip: Option<String>,
17
20
}
+8
-1
src/mac.rs
···
1
1
use std::{fmt::Display, net::UdpSocket, num::ParseIntError, str::FromStr};
2
2
3
3
-
use serde::{Deserialize, Deserializer, de::Error};
3
3
+
use serde::{Deserialize, Deserializer, Serializer, de::Error};
4
4
use thiserror::Error;
5
5
6
6
#[derive(Clone, Debug)]
···
75
75
{
76
76
MacAddress::from_str(&String::deserialize(de)?).map_err(Error::custom)
77
77
}
78
78
+
79
79
+
pub fn serialize_mac<S>(mac: &MacAddress, se: S) -> Result<S::Ok, S::Error>
80
80
+
where
81
81
+
S: Serializer,
82
82
+
{
83
83
+
se.serialize_str(&mac.to_string())
84
84
+
}
+2
-2
src/main.rs
···
22
22
for (k, v) in &config.targets {
23
23
println!("target: {k}: {} ({:?})", v.mac, v.ip);
24
24
}
25
25
-
let listener = tokio::net::TcpListener::bind(config.binding).await?;
26
26
-
axum::serve(listener, server::router()).await?;
25
25
+
let listener = tokio::net::TcpListener::bind(&config.binding).await?;
26
26
+
axum::serve(listener, server::router(config)).await?;
27
27
28
28
Ok(())
29
29
}
+21
-6
src/server.rs
···
1
1
-
use axum::{Json, Router, http::Response, routing::post};
1
1
+
use std::sync::Arc;
2
2
+
3
3
+
use axum::{
4
4
+
Json, Router,
5
5
+
extract::State,
6
6
+
http::Response,
7
7
+
routing::{get, post},
8
8
+
};
2
9
use serde::Deserialize;
3
10
4
4
-
use crate::mac::MacAddress;
11
11
+
use crate::{config::Config, mac::MacAddress};
5
12
6
13
include!(concat!(env!("OUT_DIR"), "/mod.rs"));
7
14
8
15
#[derive(Deserialize)]
9
9
-
pub struct WakeRequest {
16
16
+
struct WakeRequest {
10
17
#[serde(deserialize_with = "crate::mac::deserialize_mac")]
11
18
mac: MacAddress,
12
19
}
13
20
14
14
-
pub async fn wake(Json(req): Json<WakeRequest>) -> Result<(), Response<String>> {
21
21
+
async fn wake(Json(req): Json<WakeRequest>) -> Result<(), Response<String>> {
15
22
println!("Waking {}", req.mac);
16
23
req.mac.wake().await.map_err(|err| {
17
24
Response::builder()
···
22
29
})
23
30
}
24
31
25
25
-
pub fn router() -> Router {
26
26
-
Router::new().route("/wake", post(wake)).merge(dist::main())
32
32
+
async fn config(State(conf): State<Arc<Config>>) -> Json<Config> {
33
33
+
Json((*conf).clone())
34
34
+
}
35
35
+
36
36
+
pub fn router(conf: Config) -> Router {
37
37
+
Router::new()
38
38
+
.route("/wake", post(wake))
39
39
+
.route("/config", get(config))
40
40
+
.with_state(Arc::new(conf))
41
41
+
.merge(dist::main())
27
42
}