device_id/
device_id.rs

1#![feature(impl_trait_in_assoc_type)]
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5use tokio::io;
6use tosic_http::prelude::HttpResponse;
7use tosic_http::server::builder::HttpServerBuilder;
8use tosic_http_macro::get;
9use tracing::dispatcher::SetGlobalDefaultError;
10
11mod logger {
12    use crate::HttpServerError;
13    #[cfg(feature = "log-subscriber")]
14    use tracing::level_filters::LevelFilter;
15    #[cfg(feature = "log-subscriber")]
16    use tracing_subscriber::fmt::format::FmtSpan;
17    #[cfg(feature = "log-subscriber")]
18    use tracing_subscriber::fmt::Layer as FmtLayer;
19    #[cfg(feature = "log-subscriber")]
20    use tracing_subscriber::layer::SubscriberExt;
21    #[cfg(feature = "log-subscriber")]
22    use tracing_subscriber::{EnvFilter, Layer, Registry};
23
24    #[cfg(feature = "log-subscriber")]
25    pub fn init_tracing() -> Result<(), HttpServerError> {
26        let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
27            #[cfg(not(debug_assertions))]
28            let level = LevelFilter::INFO;
29
30            #[cfg(debug_assertions)]
31            let level = LevelFilter::DEBUG;
32
33            EnvFilter::builder()
34                .with_default_directive(level.into())
35                .from_env_lossy()
36        });
37        let def_layer = FmtLayer::new()
38            .with_line_number(true)
39            .with_span_events(FmtSpan::CLOSE)
40            .with_level(true)
41            .with_target(true)
42            .with_thread_names(true)
43            .with_thread_ids(true)
44            .compact()
45            .with_filter(filter);
46
47        let subscriber = Registry::default().with(def_layer);
48
49        tracing::subscriber::set_global_default(subscriber)?;
50
51        Ok(())
52    }
53
54    #[cfg(all(feature = "console-subscriber", not(feature = "log-subscriber")))]
55    pub fn init_tracing() -> Result<(), HttpServerError> {
56        console_subscriber::init();
57
58        Ok(())
59    }
60}
61
62#[derive(Debug, Error)]
63enum HttpServerError {
64    #[error(transparent)]
65    Tracing(#[from] SetGlobalDefaultError),
66    #[error(transparent)]
67    Io(#[from] io::Error),
68}
69
70#[derive(Debug, Serialize, Deserialize)]
71pub struct Device {
72    pub id: i32,
73    pub mac: String,
74    pub firmware: String,
75}
76
77#[get("/api/devices")]
78async fn devices() -> HttpResponse {
79    let devices = [
80        Device {
81            id: 1,
82            mac: String::from("5F-33-CC-1F-43-82"),
83            firmware: String::from("2.1.6"),
84        },
85        Device {
86            id: 2,
87            mac: String::from("EF-2B-C4-F5-D6-34"),
88            firmware: String::from("2.1.5"),
89        },
90        Device {
91            id: 3,
92            mac: String::from("62-46-13-B7-B3-A1"),
93            firmware: String::from("3.0.0"),
94        },
95        Device {
96            id: 4,
97            mac: String::from("96-A8-DE-5B-77-14"),
98            firmware: String::from("1.0.1"),
99        },
100        Device {
101            id: 5,
102            mac: String::from("7E-3B-62-A6-09-12"),
103            firmware: String::from("3.5.6"),
104        },
105    ];
106
107    HttpResponse::Ok().json(&devices)
108}
109
110#[tokio::main]
111async fn main() -> Result<(), HttpServerError> {
112    logger::init_tracing()?;
113
114    let server = HttpServerBuilder::default()
115        .bind("0.0.0.0:4221")
116        .service(devices)
117        .build()
118        .await?;
119
120    match server.serve().await {
121        Ok(_) => (),
122        Err(e) => panic!("Failed to serve: {}", e),
123    }
124
125    Ok(())
126}