1use std::fs;
2use std::net::IpAddr;
3use std::path::Path;
4use anyhow::Context;
5use axum::{Json, Router, Server, ServiceExt};
6use axum::extract::{State};
7use axum::routing::{get, IntoMakeService};
8use hyperlocal::{SocketIncoming, UnixServerExt};
9use crate::plumber::Plumber;
10use crate::resolver::NameResolver;
11
12pub fn build_server(path: impl AsRef<Path>, name_resolver: NameResolver) -> anyhow::Result<Server<SocketIncoming, IntoMakeService<Router>>> {
13 if path.as_ref().exists() {
14 fs::remove_file(path.as_ref())
15 .context("Could not remove old socket!")?;
16 }
17
18 let app = Router::new()
19 .route("/list", get(list_endpoints))
20 .route("/resolve/:name", get(resolve_endpoint))
21 .with_state(name_resolver);
22
23 let srv = axum::Server::bind_unix(path)?
24 .serve(app.into_make_service());
25
26 Ok(srv)
27}
28
29#[derive(serde::Serialize, serde::Deserialize, Debug)]
30pub struct Endpoint {
31 pub ip: IpAddr,
32}
33
34async fn list_endpoints() -> Json<Vec<Endpoint>> {
35 Json(vec![])
36}
37
38async fn resolve_endpoint(
39 axum::extract::Path(name): axum::extract::Path<String>,
40 State(state): State<NameResolver>
41) -> Json<Option<Endpoint>> {
42 let res = state.resolve(&name)
43 .map(|ip| Endpoint { ip });
44
45 Json(res)
46}