//! Имитатор термометра use rand::prelude::*; use std::io::Read; use std::net::{IpAddr, SocketAddr}; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; struct Params { addr: SocketAddr, interval: Duration, } const CONFIG_FILE: &str = "thermometer_mock.cfg"; fn read_parameters_from_file() -> Result { let mut file = std::fs::File::open(CONFIG_FILE)?; let mut content = String::new(); file.read_to_string(&mut content)?; let lines = content.split("\n").collect::>(); let addr = lines .first() .map(|v| SocketAddr::from_str(v)) .ok_or(std::io::Error::other("no address found in config file"))? .map_err(std::io::Error::other)?; let interval = lines .get(1) .map(|v| v.parse::()) .ok_or(std::io::Error::other("no interval found in config file"))? .map(Duration::from_millis) .map_err(std::io::Error::other)?; Ok(Params { addr, interval }) } fn generate_temperature() -> f32 { rand::rng().random_range(18.0..23.0) } fn main() -> Result<(), Box> { let params = read_parameters_from_file()?; let rt = tokio::runtime::Builder::new_current_thread().enable_all().build()?; rt.block_on(async move { let socket = Arc::new(tokio::net::UdpSocket::bind(SocketAddr::new(IpAddr::from([127, 0, 0, 1]), 10003)).await?); let mut interval = tokio::time::interval(params.interval); loop { interval.tick().await; let new_temperature = generate_temperature(); let data = new_temperature.to_le_bytes(); socket.send_to(&data, ¶ms.addr).await?; } }) }